From 87cd7145c9d24bcc1812ae200012e875fc61aff2 Mon Sep 17 00:00:00 2001 From: KevinVdV Date: Wed, 24 Sep 2014 16:16:06 +0200 Subject: [PATCH] Support Metadata On All DSpaceObjects --- .../app/itemupdate/DeleteMetadataAction.java | 2 +- .../RequestItemMetadataStrategy.java | 4 +- .../MetadataAuthorityISSNExtractor.java | 2 +- .../submit/MetadataValueISSNExtractor.java | 2 +- .../org/dspace/app/util/SyndicationFeed.java | 14 +- .../java/org/dspace/browse/BrowseItem.java | 59 +- .../dspace/browse/BrowseItemDAOOracle.java | 16 +- .../dspace/browse/BrowseItemDAOPostgres.java | 16 +- .../dspace/browse/SolrBrowseCreateDAO.java | 2 +- .../java/org/dspace/content/Bitstream.java | 121 +- .../main/java/org/dspace/content/Bundle.java | 25 +- .../java/org/dspace/content/Collection.java | 92 +- .../java/org/dspace/content/Community.java | 159 ++- .../java/org/dspace/content/DSpaceObject.java | 1082 ++++++++++++++++- .../main/java/org/dspace/content/Item.java | 978 +-------------- .../org/dspace/content/MetadataField.java | 58 +- .../org/dspace/content/MetadataValue.java | 61 +- .../org/dspace/content/SupervisedItem.java | 6 +- .../dspace/content/service/ItemService.java | 2 +- .../ctask/general/AbstractTranslator.java | 2 +- .../ctask/general/MetadataWebService.java | 2 +- .../ctask/general/RequiredMetadata.java | 2 +- .../org/dspace/discovery/SolrServiceImpl.java | 2 +- .../main/java/org/dspace/eperson/EPerson.java | 206 ++-- .../main/java/org/dspace/eperson/Group.java | 209 ++-- .../identifier/EZIDIdentifierProvider.java | 2 +- .../dspace/storage/rdbms/DatabaseManager.java | 199 +-- .../DSpaceWorkspaceItemOutputGenerator.java | 2 +- .../org/dspace/submit/step/DescribeStep.java | 4 +- .../java/org/dspace/AbstractUnitTest.java | 4 + .../org/dspace/content/CollectionTest.java | 15 +- .../org/dspace/content/CommunityTest.java | 4 - .../java/org/dspace/content/ItemTest.java | 9 +- .../org/dspace/content/MetadataFieldTest.java | 7 +- .../content/MetadataIntegrationTest.java | 7 +- .../org/dspace/content/MetadataValueTest.java | 13 +- .../src/test/resources/database_schema.sql | 42 +- .../app/webui/jsptag/BrowseListTag.java | 7 +- .../webui/util/MetadataStyleSelection.java | 2 +- .../main/webapp/dspace-admin/curate-item.jsp | 2 +- .../src/main/webapp/submit/edit-metadata.jsp | 4 +- .../src/main/webapp/tools/curate-item.jsp | 2 +- .../DSpaceAtLeastOneMetadataFilter.java | 3 +- .../filter/DSpaceMetadataExistsFilter.java | 3 +- .../xoai/filter/DSpaceSetSpecFilter.java | 6 +- .../DSpaceDatabaseQueryResolverTest.java | 5 +- .../dspace/sword/ItemCollectionGenerator.java | 4 +- .../org/dspace/sword/ItemEntryGenerator.java | 10 +- .../sword2/AtomStatementDisseminator.java | 2 +- .../sword2/CollectionListManagerDSpace.java | 2 +- .../org/dspace/sword2/ReceiptGenerator.java | 12 +- .../statisticsElasticSearch/CSVOutputter.java | 7 +- .../ElasticSearchStatsViewer.java | 2 +- .../submission/submit/DescribeStep.java | 4 +- .../java/org/dspace/springmvc/BibTexView.java | 12 +- .../java/org/dspace/springmvc/RisView.java | 18 +- .../config/registries/dublin-core-types.xml | 14 + dspace/config/registries/eperson-types.xml | 47 + dspace/etc/oracle/database_schema.sql | 39 +- dspace/etc/oracle/database_schema_4-5.sql | 346 ++++++ dspace/etc/postgres/database_schema.sql | 42 +- dspace/etc/postgres/database_schema_4_5.sql | 313 +++++ dspace/src/main/config/build.xml | 64 +- 63 files changed, 2721 insertions(+), 1683 deletions(-) create mode 100644 dspace/config/registries/eperson-types.xml diff --git a/dspace-api/src/main/java/org/dspace/app/itemupdate/DeleteMetadataAction.java b/dspace-api/src/main/java/org/dspace/app/itemupdate/DeleteMetadataAction.java index 948ebef42ee8..d911c761cda4 100644 --- a/dspace-api/src/main/java/org/dspace/app/itemupdate/DeleteMetadataAction.java +++ b/dspace-api/src/main/java/org/dspace/app/itemupdate/DeleteMetadataAction.java @@ -38,7 +38,7 @@ public void execute(Context context, ItemArchive itarch, boolean isTest, for (String f : targetFields) { DtoMetadata dummy = DtoMetadata.create(f, Item.ANY, ""); - DCValue[] ardcv = item.getMetadata(f); + DCValue[] ardcv = item.getMetadataByMetadataString(f); ItemUpdate.pr("Metadata to be deleted: "); for (DCValue dcv : ardcv) diff --git a/dspace-api/src/main/java/org/dspace/app/requestitem/RequestItemMetadataStrategy.java b/dspace-api/src/main/java/org/dspace/app/requestitem/RequestItemMetadataStrategy.java index b5ed3a3e67b3..a45ec4d3b815 100644 --- a/dspace-api/src/main/java/org/dspace/app/requestitem/RequestItemMetadataStrategy.java +++ b/dspace-api/src/main/java/org/dspace/app/requestitem/RequestItemMetadataStrategy.java @@ -35,14 +35,14 @@ public RequestItemAuthor getRequestItemAuthor(Context context, Item item) throws SQLException { if (emailMetadata != null) { - DCValue[] vals = item.getMetadata(emailMetadata); + DCValue[] vals = item.getMetadataByMetadataString(emailMetadata); if (vals.length > 0) { String email = vals[0].value; String fullname = null; if (fullNameMatadata != null) { - DCValue[] nameVals = item.getMetadata(fullNameMatadata); + DCValue[] nameVals = item.getMetadataByMetadataString(fullNameMatadata); if (nameVals.length > 0) { fullname = nameVals[0].value; diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/submit/MetadataAuthorityISSNExtractor.java b/dspace-api/src/main/java/org/dspace/app/sherpa/submit/MetadataAuthorityISSNExtractor.java index 0e34f391b88b..79f518685ef0 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/submit/MetadataAuthorityISSNExtractor.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/submit/MetadataAuthorityISSNExtractor.java @@ -29,7 +29,7 @@ public List getISSNs(Context context, Item item) List values = new ArrayList(); for (String metadata : metadataList) { - DCValue[] dcvalues = item.getMetadata(metadata); + DCValue[] dcvalues = item.getMetadataByMetadataString(metadata); for (DCValue dcvalue : dcvalues) { values.add(dcvalue.authority); diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/submit/MetadataValueISSNExtractor.java b/dspace-api/src/main/java/org/dspace/app/sherpa/submit/MetadataValueISSNExtractor.java index bf7e52106eb3..c14608a106ee 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/submit/MetadataValueISSNExtractor.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/submit/MetadataValueISSNExtractor.java @@ -29,7 +29,7 @@ public List getISSNs(Context context, Item item) List values = new ArrayList(); for (String metadata : metadataList) { - DCValue[] dcvalues = item.getMetadata(metadata); + DCValue[] dcvalues = item.getMetadataByMetadataString(metadata); for (DCValue dcvalue : dcvalues) { values.add(dcvalue.value); diff --git a/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java b/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java index eb88ff704f81..47a38e1e441f 100644 --- a/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java +++ b/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java @@ -265,7 +265,7 @@ else if (dso.getType() == Constants.COMMUNITY) df = df.replaceAll("\\(date\\)", ""); } - DCValue dcv[] = item.getMetadata(df); + DCValue dcv[] = item.getMetadataByMetadataString(df); if (dcv.length > 0) { String fieldLabel = labels.get(MSG_METADATA + df); @@ -298,7 +298,7 @@ else if (dso.getType() == Constants.COMMUNITY) } // This gets the authors into an ATOM feed - DCValue authors[] = item.getMetadata(authorField); + DCValue authors[] = item.getMetadataByMetadataString(authorField); if (authors.length > 0) { List creators = new ArrayList(); @@ -318,7 +318,7 @@ else if (dso.getType() == Constants.COMMUNITY) DCModule dc = new DCModuleImpl(); if (dcCreatorField != null) { - DCValue dcAuthors[] = item.getMetadata(dcCreatorField); + DCValue dcAuthors[] = item.getMetadataByMetadataString(dcCreatorField); if (dcAuthors.length > 0) { List creators = new ArrayList(); @@ -331,7 +331,7 @@ else if (dso.getType() == Constants.COMMUNITY) } if (dcDateField != null && !hasDate) { - DCValue v[] = item.getMetadata(dcDateField); + DCValue v[] = item.getMetadataByMetadataString(dcDateField); if (v.length > 0) { dc.setDate((new DCDate(v[0].value)).toDate()); @@ -339,7 +339,7 @@ else if (dso.getType() == Constants.COMMUNITY) } if (dcDescriptionField != null) { - DCValue v[] = item.getMetadata(dcDescriptionField); + DCValue v[] = item.getMetadataByMetadataString(dcDescriptionField); if (v.length > 0) { StringBuffer descs = new StringBuffer(); @@ -381,7 +381,7 @@ else if (dso.getType() == Constants.COMMUNITY) } //Also try to add an external value from dc.identifier.other // We are assuming that if this is set, then it is a media file - DCValue[] externalMedia = item.getMetadata(externalSourceField); + DCValue[] externalMedia = item.getMetadataByMetadataString(externalSourceField); if(externalMedia.length > 0) { for(int i = 0; i< externalMedia.length; i++) @@ -567,7 +567,7 @@ private String localize(Map labels, String s) // spoonful of syntactic sugar when we only need first value private String getOneDC(Item item, String field) { - DCValue dcv[] = item.getMetadata(field); + DCValue dcv[] = item.getMetadataByMetadataString(field); return (dcv.length > 0) ? dcv[0].value : null; } } diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowseItem.java b/dspace-api/src/main/java/org/dspace/browse/BrowseItem.java index 72043b830ab5..d4d0284d6896 100644 --- a/dspace-api/src/main/java/org/dspace/browse/BrowseItem.java +++ b/dspace-api/src/main/java/org/dspace/browse/BrowseItem.java @@ -40,9 +40,6 @@ public class BrowseItem extends DSpaceObject /** Logger */ private static Logger log = Logger.getLogger(BrowseItem.class); - /** DSpace context */ - private Context context; - /** a List of all the metadata */ private List metadata = new ArrayList(); @@ -62,16 +59,15 @@ public class BrowseItem extends DSpaceObject private String handle = null; /** - * Construct a new browse item with the given context and the database id + * Construct a new browse item with the given ourContext and the database id * - * @param context the DSpace context + * @param context the DSpace ourContext * @param id the database id of the item * @param in_archive * @param withdrawn */ - public BrowseItem(Context context, int id, boolean in_archive, boolean withdrawn, boolean discoverable) - { - this.context = context; + public BrowseItem(Context context, int id, boolean in_archive, boolean withdrawn, boolean discoverable) { + super(context); this.id = id; this.in_archive = in_archive; this.withdrawn = withdrawn; @@ -88,18 +84,20 @@ public BrowseItem(Context context, int id, boolean in_archive, boolean withdrawn * @return array of matching values * @throws SQLException */ - public DCValue[] getMetadata(String schema, String element, String qualifier, String lang) - throws SQLException - { + public DCValue[] getMetadata(String schema, String element, String qualifier, String lang) { try { - BrowseItemDAO dao = BrowseDAOFactory.getItemInstance(context); + BrowseItemDAO dao = BrowseDAOFactory.getItemInstance(ourContext); // if the qualifier is a wildcard, we have to get it out of the // database if (Item.ANY.equals(qualifier)) { - return dao.queryMetadata(id, schema, element, qualifier, lang); + try { + return dao.queryMetadata(id, schema, element, qualifier, lang); + } catch (SQLException e) { + log.error("caught exception: ", e); + } } if (!metadata.isEmpty()) @@ -119,7 +117,12 @@ public DCValue[] getMetadata(String schema, String element, String qualifier, St if (values.isEmpty()) { - DCValue[] dcvs = dao.queryMetadata(id, schema, element, qualifier, lang); + DCValue[] dcvs = new DCValue[0]; + try { + dcvs = dao.queryMetadata(id, schema, element, qualifier, lang); + } catch (SQLException e) { + log.error("caught exception: ", e); + } if (dcvs != null) { Collections.addAll(metadata, dcvs); @@ -135,7 +138,12 @@ public DCValue[] getMetadata(String schema, String element, String qualifier, St } else { - DCValue[] dcvs = dao.queryMetadata(id, schema, element, qualifier, lang); + DCValue[] dcvs = new DCValue[0]; + try { + dcvs = dao.queryMetadata(id, schema, element, qualifier, lang); + } catch (SQLException e) { + log.error("caught exception: ", e); + } if (dcvs != null) { Collections.addAll(metadata, dcvs); @@ -286,7 +294,7 @@ public String getHandle() { try { - this.handle = HandleManager.findHandle(context, this); + this.handle = HandleManager.findHandle(ourContext, this); } catch (SQLException e) { @@ -310,7 +318,7 @@ public Thumbnail getThumbnail() throws SQLException { // instantiate an item for this one. Not nice. - Item item = Item.find(context, id); + Item item = Item.find(ourContext, id); if (item == null) { @@ -353,7 +361,7 @@ public Thumbnail getThumbnail() if ((original[0].getBitstreams().length > 1) && (original[0].getPrimaryBitstreamID() > -1)) { - originalBitstream = Bitstream.find(context, original[0].getPrimaryBitstreamID()); + originalBitstream = Bitstream.find(ourContext, original[0].getPrimaryBitstreamID()); thumbnailBitstream = thumbs[0].getBitstreamByName(originalBitstream.getName() + ".jpg"); } else @@ -363,7 +371,7 @@ public Thumbnail getThumbnail() } if ((thumbnailBitstream != null) - && (AuthorizeManager.authorizeActionBoolean(context, thumbnailBitstream, Constants.READ))) + && (AuthorizeManager.authorizeActionBoolean(ourContext, thumbnailBitstream, Constants.READ))) { return new Thumbnail(thumbnailBitstream, originalBitstream); } @@ -374,23 +382,12 @@ public Thumbnail getThumbnail() public String getName() { - // FIXME: there is an exception handling problem here - try - { - DCValue t[] = getMetadata("dc", "title", null, Item.ANY); - return (t.length >= 1) ? t[0].value : null; - } - catch (SQLException sqle) - { - log.error("caught exception: ", sqle); - return null; - } + return getMetadataFirstValue(MetadataSchema.DC_SCHEMA, "title", null, Item.ANY); } @Override public void update() throws SQLException, AuthorizeException { - } @Override diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAOOracle.java b/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAOOracle.java index bd2e84038c03..236fabb39935 100644 --- a/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAOOracle.java +++ b/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAOOracle.java @@ -7,6 +7,7 @@ */ package org.dspace.browse; +import org.dspace.core.Constants; import org.dspace.storage.rdbms.TableRowIterator; import org.dspace.storage.rdbms.DatabaseManager; import org.dspace.storage.rdbms.TableRow; @@ -26,31 +27,34 @@ public class BrowseItemDAOOracle implements BrowseItemDAO /** query to get the text value of a metadata element only (qualifier is NULL) */ private String getByMetadataElement = "SELECT authority, confidence, text_value,text_lang,element,qualifier FROM metadatavalue, metadatafieldregistry, metadataschemaregistry " + - "WHERE metadatavalue.item_id = ? " + + "WHERE metadatavalue.resource_id = ? " + " AND metadatavalue.metadata_field_id = metadatafieldregistry.metadata_field_id " + " AND metadatafieldregistry.element = ? " + " AND metadatafieldregistry.qualifier IS NULL " + " AND metadatafieldregistry.metadata_schema_id=metadataschemaregistry.metadata_schema_id " + " AND metadataschemaregistry.short_id = ? " + + " AND metadatavalue.resource_type_id = ? " + " ORDER BY metadatavalue.metadata_field_id, metadatavalue.place"; /** query to get the text value of a metadata element and qualifier */ private String getByMetadata = "SELECT authority, confidence, text_value,text_lang,element,qualifier FROM metadatavalue, metadatafieldregistry, metadataschemaregistry " + - "WHERE metadatavalue.item_id = ? " + + "WHERE metadatavalue.resource_id = ? " + " AND metadatavalue.metadata_field_id = metadatafieldregistry.metadata_field_id " + " AND metadatafieldregistry.element = ? " + " AND metadatafieldregistry.qualifier = ? " + " AND metadatafieldregistry.metadata_schema_id=metadataschemaregistry.metadata_schema_id " + " AND metadataschemaregistry.short_id = ? " + + " AND metadatavalue.resource_type_id = ? " + " ORDER BY metadatavalue.metadata_field_id, metadatavalue.place"; /** query to get the text value of a metadata element with the wildcard qualifier (*) */ private String getByMetadataAnyQualifier = "SELECT authority, confidence, text_value,text_lang,element,qualifier FROM metadatavalue, metadatafieldregistry, metadataschemaregistry " + - "WHERE metadatavalue.item_id = ? " + + "WHERE metadatavalue.resource_id = ? " + " AND metadatavalue.metadata_field_id = metadatafieldregistry.metadata_field_id " + " AND metadatafieldregistry.element = ? " + " AND metadatafieldregistry.metadata_schema_id=metadataschemaregistry.metadata_schema_id " + " AND metadataschemaregistry.short_id = ? " + + " AND metadatavalue.resource_type_id = ? " + " ORDER BY metadatavalue.metadata_field_id, metadatavalue.place"; /** DSpace context */ @@ -101,17 +105,17 @@ public DCValue[] queryMetadata(int itemId, String schema, String element, String { if (qualifier == null) { - Object[] params = { Integer.valueOf(itemId), element, schema }; + Object[] params = { Integer.valueOf(itemId), element, schema, Constants.ITEM }; tri = DatabaseManager.query(context, getByMetadataElement, params); } else if (Item.ANY.equals(qualifier)) { - Object[] params = { Integer.valueOf(itemId), element, schema }; + Object[] params = { Integer.valueOf(itemId), element, schema, Constants.ITEM }; tri = DatabaseManager.query(context, getByMetadataAnyQualifier, params); } else { - Object[] params = { Integer.valueOf(itemId), element, qualifier, schema }; + Object[] params = { Integer.valueOf(itemId), element, qualifier, schema, Constants.ITEM }; tri = DatabaseManager.query(context, getByMetadata, params); } diff --git a/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAOPostgres.java b/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAOPostgres.java index 851cd47cfb9d..5bf221a5a271 100644 --- a/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAOPostgres.java +++ b/dspace-api/src/main/java/org/dspace/browse/BrowseItemDAOPostgres.java @@ -7,6 +7,7 @@ */ package org.dspace.browse; +import org.dspace.core.Constants; import org.dspace.storage.rdbms.TableRowIterator; import org.dspace.storage.rdbms.DatabaseManager; import org.dspace.storage.rdbms.TableRow; @@ -25,31 +26,34 @@ public class BrowseItemDAOPostgres implements BrowseItemDAO /** query to get the text value of a metadata element only (qualifier is NULL) */ private String getByMetadataElement = "SELECT authority, confidence, text_value,text_lang,element,qualifier FROM metadatavalue, metadatafieldregistry, metadataschemaregistry " + - "WHERE metadatavalue.item_id = ? " + + "WHERE metadatavalue.resource_id = ? " + " AND metadatavalue.metadata_field_id = metadatafieldregistry.metadata_field_id " + " AND metadatafieldregistry.element = ? " + " AND metadatafieldregistry.qualifier IS NULL " + " AND metadatafieldregistry.metadata_schema_id=metadataschemaregistry.metadata_schema_id " + " AND metadataschemaregistry.short_id = ? " + + " AND metadatavalue.resource_type_id = ? " + " ORDER BY metadatavalue.metadata_field_id, metadatavalue.place"; /** query to get the text value of a metadata element and qualifier */ private String getByMetadata = "SELECT authority, confidence, text_value,text_lang,element,qualifier FROM metadatavalue, metadatafieldregistry, metadataschemaregistry " + - "WHERE metadatavalue.item_id = ? " + + "WHERE metadatavalue.resource_id = ? " + " AND metadatavalue.metadata_field_id = metadatafieldregistry.metadata_field_id " + " AND metadatafieldregistry.element = ? " + " AND metadatafieldregistry.qualifier = ? " + " AND metadatafieldregistry.metadata_schema_id=metadataschemaregistry.metadata_schema_id " + " AND metadataschemaregistry.short_id = ? " + + " AND metadatavalue.resource_type_id = ? " + " ORDER BY metadatavalue.metadata_field_id, metadatavalue.place"; /** query to get the text value of a metadata element with the wildcard qualifier (*) */ private String getByMetadataAnyQualifier = "SELECT authority, confidence, text_value,text_lang,element,qualifier FROM metadatavalue, metadatafieldregistry, metadataschemaregistry " + - "WHERE metadatavalue.item_id = ? " + + "WHERE metadatavalue.resource_id = ? " + " AND metadatavalue.metadata_field_id = metadatafieldregistry.metadata_field_id " + " AND metadatafieldregistry.element = ? " + " AND metadatafieldregistry.metadata_schema_id=metadataschemaregistry.metadata_schema_id " + " AND metadataschemaregistry.short_id = ? " + + " AND metadatavalue.resource_type_id = ? " + " ORDER BY metadatavalue.metadata_field_id, metadatavalue.place"; /** DSpace context */ @@ -101,16 +105,16 @@ public DCValue[] queryMetadata(int itemId, String schema, String element, String if (qualifier == null) { Object[] params = { Integer.valueOf(itemId), element, schema }; - tri = DatabaseManager.query(context, getByMetadataElement, params); + tri = DatabaseManager.query(context, getByMetadataElement, params, Constants.ITEM); } else if (Item.ANY.equals(qualifier)) { Object[] params = { Integer.valueOf(itemId), element, schema }; - tri = DatabaseManager.query(context, getByMetadataAnyQualifier, params); + tri = DatabaseManager.query(context, getByMetadataAnyQualifier, params, Constants.ITEM); } else { - Object[] params = { Integer.valueOf(itemId), element, qualifier, schema }; + Object[] params = { Integer.valueOf(itemId), element, qualifier, schema, Constants.ITEM }; tri = DatabaseManager.query(context, getByMetadata, params); } diff --git a/dspace-api/src/main/java/org/dspace/browse/SolrBrowseCreateDAO.java b/dspace-api/src/main/java/org/dspace/browse/SolrBrowseCreateDAO.java index 43bafc0154e6..02eb551d93bf 100644 --- a/dspace-api/src/main/java/org/dspace/browse/SolrBrowseCreateDAO.java +++ b/dspace-api/src/main/java/org/dspace/browse/SolrBrowseCreateDAO.java @@ -330,7 +330,7 @@ public void additionalIndex(Context context, DSpaceObject dso, SolrInputDocument { for (SortOption so : SortOption.getSortOptions()) { - DCValue[] dcvalue = item.getMetadata(so.getMetadata()); + DCValue[] dcvalue = item.getMetadataByMetadataString(so.getMetadata()); if (dcvalue != null && dcvalue.length > 0) { String nValue = OrderFormat diff --git a/dspace-api/src/main/java/org/dspace/content/Bitstream.java b/dspace-api/src/main/java/org/dspace/content/Bitstream.java index 440a667af9ca..a953390c0658 100644 --- a/dspace-api/src/main/java/org/dspace/content/Bitstream.java +++ b/dspace-api/src/main/java/org/dspace/content/Bitstream.java @@ -41,8 +41,6 @@ public class Bitstream extends DSpaceObject /** log4j logger */ private static Logger log = Logger.getLogger(Bitstream.class); - /** Our context */ - private Context bContext; /** The row in the table representing this bitstream */ private TableRow bRow; @@ -53,9 +51,6 @@ public class Bitstream extends DSpaceObject /** Flag set when data is modified, for events */ private boolean modified; - /** Flag set when metadata is modified, for events */ - private boolean modifiedMetadata; - /** * Private constructor for creating a Bitstream object based on the contents * of a DB table row. @@ -68,7 +63,7 @@ public class Bitstream extends DSpaceObject */ Bitstream(Context context, TableRow row) throws SQLException { - bContext = context; + super(context); bRow = row; // Get the bitstream format @@ -91,7 +86,6 @@ public class Bitstream extends DSpaceObject context.cache(this, row.getIntColumn("bitstream_id")); modified = false; - modifiedMetadata = false; clearDetails(); } @@ -298,9 +292,8 @@ public void setSequenceID(int sid) * * @return the name of the bitstream */ - public String getName() - { - return bRow.getStringColumn("name"); + public String getName(){ + return getMetadataFirstValue(MetadataSchema.DC_SCHEMA, "title", null, Item.ANY); } /** @@ -309,11 +302,8 @@ public String getName() * @param n * the new name of the bitstream */ - public void setName(String n) - { - bRow.setColumn("name", n); - modifiedMetadata = true; - addDetails("Name"); + public void setName(String n) { + setMetadataSingleValue(MetadataSchema.DC_SCHEMA, "title", null, null, n); } /** @@ -325,7 +315,7 @@ public void setName(String n) */ public String getSource() { - return bRow.getStringColumn("source"); + return getMetadataFirstValue(MetadataSchema.DC_SCHEMA, "source", null, Item.ANY); } /** @@ -334,11 +324,8 @@ public String getSource() * @param n * the new source of the bitstream */ - public void setSource(String n) - { - bRow.setColumn("source", n); - modifiedMetadata = true; - addDetails("Source"); + public void setSource(String n) { + setMetadataSingleValue(MetadataSchema.DC_SCHEMA, "source", null, null, n); } /** @@ -349,7 +336,7 @@ public void setSource(String n) */ public String getDescription() { - return bRow.getStringColumn("description"); + return getMetadataFirstValue(MetadataSchema.DC_SCHEMA, "description", null, Item.ANY); } /** @@ -358,11 +345,8 @@ public String getDescription() * @param n * the new description of the bitstream */ - public void setDescription(String n) - { - bRow.setColumn("description", n); - modifiedMetadata = true; - addDetails("Description"); + public void setDescription(String n) { + setMetadataSingleValue(MetadataSchema.DC_SCHEMA, "description", null, null, n); } /** @@ -403,14 +387,9 @@ public long getSize() * the user's description of the format * @throws SQLException */ - public void setUserFormatDescription(String desc) throws SQLException - { - // FIXME: Would be better if this didn't throw an SQLException, - // but we need to find the unknown format! + public void setUserFormatDescription(String desc) throws SQLException { setFormat(null); - bRow.setColumn("user_format_description", desc); - modifiedMetadata = true; - addDetails("UserFormatDescription"); + setMetadataSingleValue(MetadataSchema.DC_SCHEMA, "format", null, null, desc); } /** @@ -421,7 +400,7 @@ public void setUserFormatDescription(String desc) throws SQLException */ public String getUserFormatDescription() { - return bRow.getStringColumn("user_format_description"); + return getMetadataFirstValue(MetadataSchema.DC_SCHEMA, "format", null, Item.ANY); } /** @@ -435,7 +414,7 @@ public String getFormatDescription() if (bitstreamFormat.getShortDescription().equals("Unknown")) { // Get user description if there is one - String desc = bRow.getStringColumn("user_format_description"); + String desc = getUserFormatDescription(); if (desc == null) { @@ -476,7 +455,7 @@ public void setFormat(BitstreamFormat f) throws SQLException if (f == null) { // Use "Unknown" format - bitstreamFormat = BitstreamFormat.findUnknown(bContext); + bitstreamFormat = BitstreamFormat.findUnknown(ourContext); } else { @@ -484,7 +463,7 @@ public void setFormat(BitstreamFormat f) throws SQLException } // Remove user type description - bRow.setColumnNull("user_format_description"); + clearMetadata(MetadataSchema.DC_SCHEMA,"format",null, Item.ANY); // Update the ID in the table row bRow.setColumn("bitstream_format_id", bitstreamFormat.getID()); @@ -501,27 +480,24 @@ public void setFormat(BitstreamFormat f) throws SQLException public void update() throws SQLException, AuthorizeException { // Check authorisation - AuthorizeManager.authorizeAction(bContext, this, Constants.WRITE); + AuthorizeManager.authorizeAction(ourContext, this, Constants.WRITE); - log.info(LogManager.getHeader(bContext, "update_bitstream", + log.info(LogManager.getHeader(ourContext, "update_bitstream", "bitstream_id=" + getID())); + DatabaseManager.update(ourContext, bRow); + if (modified) { - bContext.addEvent(new Event(Event.MODIFY, Constants.BITSTREAM, - getID(), null, getIdentifiers(bContext))); + ourContext.addEvent(new Event(Event.MODIFY, Constants.BITSTREAM, getID(), null, getIdentifiers(ourContext))); modified = false; } if (modifiedMetadata) { - bContext.addEvent(new Event(Event.MODIFY_METADATA, - Constants.BITSTREAM, getID(), getDetails(), - getIdentifiers(bContext))); - modifiedMetadata = false; + updateMetadata(); clearDetails(); } - DatabaseManager.update(bContext, bRow); } /** @@ -535,28 +511,30 @@ void delete() throws SQLException // changed to a check on remove // Check authorisation - //AuthorizeManager.authorizeAction(bContext, this, Constants.DELETE); - log.info(LogManager.getHeader(bContext, "delete_bitstream", + //AuthorizeManager.authorizeAction(ourContext, this, Constants.DELETE); + log.info(LogManager.getHeader(ourContext, "delete_bitstream", "bitstream_id=" + getID())); - bContext.addEvent(new Event(Event.DELETE, Constants.BITSTREAM, getID(), - String.valueOf(getSequenceID()), getIdentifiers(bContext))); + ourContext.addEvent(new Event(Event.DELETE, Constants.BITSTREAM, getID(), + String.valueOf(getSequenceID()), getIdentifiers(ourContext))); // Remove from cache - bContext.removeCached(this, getID()); + ourContext.removeCached(this, getID()); // Remove policies - AuthorizeManager.removeAllPolicies(bContext, this); + AuthorizeManager.removeAllPolicies(ourContext, this); // Remove references to primary bitstreams in bundle String query = "update bundle set primary_bitstream_id = "; query += (oracle ? "''" : "Null") + " where primary_bitstream_id = ? "; - DatabaseManager.updateQuery(bContext, + DatabaseManager.updateQuery(ourContext, query, bRow.getIntColumn("bitstream_id")); // Remove bitstream itself - BitstreamStorageManager.delete(bContext, bRow + BitstreamStorageManager.delete(ourContext, bRow .getIntColumn("bitstream_id")); + + removeMetadataFromDatabase(); } /** @@ -568,7 +546,7 @@ void delete() throws SQLException boolean isDeleted() throws SQLException { String query = "select count(*) as mycount from Bitstream where deleted = '1' and bitstream_id = ? "; - TableRowIterator tri = DatabaseManager.query(bContext, query, bRow.getIntColumn("bitstream_id")); + TableRowIterator tri = DatabaseManager.query(ourContext, query, bRow.getIntColumn("bitstream_id")); long count = 0; try @@ -600,9 +578,9 @@ public InputStream retrieve() throws IOException, SQLException, AuthorizeException { // Maybe should return AuthorizeException?? - AuthorizeManager.authorizeAction(bContext, this, Constants.READ); + AuthorizeManager.authorizeAction(ourContext, this, Constants.READ); - return BitstreamStorageManager.retrieve(bContext, bRow + return BitstreamStorageManager.retrieve(ourContext, bRow .getIntColumn("bitstream_id")); } @@ -615,11 +593,11 @@ public InputStream retrieve() throws IOException, SQLException, public Bundle[] getBundles() throws SQLException { // Get the bundle table rows - TableRowIterator tri = DatabaseManager.queryTable(bContext, "bundle", - "SELECT bundle.* FROM bundle, bundle2bitstream WHERE " + - "bundle.bundle_id=bundle2bitstream.bundle_id AND " + - "bundle2bitstream.bitstream_id= ? ", - bRow.getIntColumn("bitstream_id")); + TableRowIterator tri = DatabaseManager.queryTable(ourContext, "bundle", + "SELECT bundle.* FROM bundle, bundle2bitstream WHERE " + + "bundle.bundle_id=bundle2bitstream.bundle_id AND " + + "bundle2bitstream.bitstream_id= ? ", + bRow.getIntColumn("bitstream_id")); // Build a list of Bundle objects List bundles = new ArrayList(); @@ -630,7 +608,7 @@ public Bundle[] getBundles() throws SQLException TableRow r = tri.next(); // First check the cache - Bundle fromCache = (Bundle) bContext.fromCache(Bundle.class, r + Bundle fromCache = (Bundle) ourContext.fromCache(Bundle.class, r .getIntColumn("bundle_id")); if (fromCache != null) @@ -639,7 +617,7 @@ public Bundle[] getBundles() throws SQLException } else { - bundles.add(new Bundle(bContext, r)); + bundles.add(new Bundle(ourContext, r)); } } } @@ -716,23 +694,23 @@ public DSpaceObject getParentObject() throws SQLException else { // is the bitstream a logo for a community or a collection? - TableRow qResult = DatabaseManager.querySingle(bContext, + TableRow qResult = DatabaseManager.querySingle(ourContext, "SELECT collection_id FROM collection " + "WHERE logo_bitstream_id = ?",getID()); if (qResult != null) { - return Collection.find(bContext,qResult.getIntColumn("collection_id")); + return Collection.find(ourContext,qResult.getIntColumn("collection_id")); } else { // is the bitstream related to a community? - qResult = DatabaseManager.querySingle(bContext, + qResult = DatabaseManager.querySingle(ourContext, "SELECT community_id FROM community " + "WHERE logo_bitstream_id = ?",getID()); if (qResult != null) { - return Community.find(bContext,qResult.getIntColumn("community_id")); + return Community.find(ourContext,qResult.getIntColumn("community_id")); } else { @@ -746,7 +724,6 @@ public DSpaceObject getParentObject() throws SQLException public void updateLastModified() { //Also fire a modified event since the bitstream HAS been modified - bContext.addEvent(new Event(Event.MODIFY, Constants.BITSTREAM, getID(), - null, getIdentifiers(bContext))); + ourContext.addEvent(new Event(Event.MODIFY, Constants.BITSTREAM, getID(), null, getIdentifiers(ourContext))); } -} +} \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/content/Bundle.java b/dspace-api/src/main/java/org/dspace/content/Bundle.java index a85815272e68..5ba978565a2b 100644 --- a/dspace-api/src/main/java/org/dspace/content/Bundle.java +++ b/dspace-api/src/main/java/org/dspace/content/Bundle.java @@ -42,9 +42,6 @@ public class Bundle extends DSpaceObject /** log4j logger */ private static Logger log = Logger.getLogger(Bundle.class); - /** Our context */ - private Context ourContext; - /** The table row corresponding to this bundle */ private TableRow bundleRow; @@ -54,9 +51,6 @@ public class Bundle extends DSpaceObject /** Flag set when data is modified, for events */ private boolean modified; - /** Flag set when metadata is modified, for events */ - private boolean modifiedMetadata; - /** * Construct a bundle object with the given table row * @@ -67,7 +61,7 @@ public class Bundle extends DSpaceObject */ Bundle(Context context, TableRow row) throws SQLException { - ourContext = context; + super(context); bundleRow = row; bitstreams = new ArrayList(); String bitstreamOrderingField = ConfigurationManager.getProperty("webui.bitstream.order.field"); @@ -134,7 +128,6 @@ public class Bundle extends DSpaceObject context.cache(this, row.getIntColumn("bundle_id")); modified = false; - modifiedMetadata = false; } /** @@ -226,7 +219,7 @@ public int getID() */ public String getName() { - return bundleRow.getStringColumn("name"); + return getMetadataFirstValue(MetadataSchema.DC_SCHEMA, "title", null, Item.ANY); } /** @@ -238,8 +231,7 @@ public String getName() */ public void setName(String name) { - bundleRow.setColumn("name", name); - modifiedMetadata = true; + setMetadataSingleValue(MetadataSchema.DC_SCHEMA, "title", null, null, name); } /** @@ -611,6 +603,8 @@ public void update() throws SQLException, AuthorizeException log.info(LogManager.getHeader(ourContext, "update_bundle", "bundle_id=" + getID())); + DatabaseManager.update(ourContext, bundleRow); + if (modified) { ourContext.addEvent(new Event(Event.MODIFY, Constants.BUNDLE, getID(), @@ -619,12 +613,9 @@ public void update() throws SQLException, AuthorizeException } if (modifiedMetadata) { - ourContext.addEvent(new Event(Event.MODIFY_METADATA, Constants.BUNDLE, - getID(), null, getIdentifiers(ourContext))); - modifiedMetadata = false; + updateMetadata(); + clearDetails(); } - - DatabaseManager.update(ourContext, bundleRow); } /** @@ -656,6 +647,8 @@ void delete() throws SQLException, AuthorizeException, IOException // Remove ourself DatabaseManager.delete(ourContext, bundleRow); + + removeMetadataFromDatabase(); } /** diff --git a/dspace-api/src/main/java/org/dspace/content/Collection.java b/dspace-api/src/main/java/org/dspace/content/Collection.java index 69b77fcb7e63..44f604649668 100644 --- a/dspace-api/src/main/java/org/dspace/content/Collection.java +++ b/dspace-api/src/main/java/org/dspace/content/Collection.java @@ -57,9 +57,6 @@ public class Collection extends DSpaceObject /** log4j category */ private static Logger log = Logger.getLogger(Collection.class); - /** Our context */ - private Context ourContext; - /** The table row corresponding to this item */ private TableRow collectionRow; @@ -75,9 +72,6 @@ public class Collection extends DSpaceObject /** Flag set when data is modified, for events */ private boolean modified; - /** Flag set when metadata is modified, for events */ - private boolean modifiedMetadata; - /** * Groups corresponding to workflow steps - NOTE these start from one, so * workflowGroups[0] corresponds to workflow_step_1. @@ -108,7 +102,7 @@ public class Collection extends DSpaceObject */ Collection(Context context, TableRow row) throws SQLException { - ourContext = context; + super(context); collectionRow = row; // Get the logo bitstream @@ -150,7 +144,6 @@ public class Collection extends DSpaceObject context.cache(this, row.getIntColumn("collection_id")); modified = false; - modifiedMetadata = false; clearDetails(); } @@ -299,10 +292,26 @@ static Collection create(Context context, String handle) throws SQLException, * @return the collections in the system * @throws SQLException */ - public static Collection[] findAll(Context context) throws SQLException - { - TableRowIterator tri = DatabaseManager.queryTable(context, "collection", - "SELECT * FROM collection ORDER BY name"); + public static Collection[] findAll(Context context) throws SQLException { + TableRowIterator tri = null; + try { + String query = "SELECT c.* FROM collection c " + + "LEFT JOIN metadatavalue m on (m.resource_id = c.collection_id and m.resource_type_id = ? and m.metadata_field_id = ?) "; + if(DatabaseManager.isOracle()){ + query += " ORDER BY cast(m.text_value as varchar2(128))"; + }else{ + query += " ORDER BY m.text_value"; + } + + tri = DatabaseManager.query(context, + query, + Constants.COLLECTION, + MetadataField.findByElement(context, MetadataSchema.find(context, MetadataSchema.DC_SCHEMA).getSchemaID(), "title", null).getFieldID() + ); + } catch (SQLException e) { + log.error("Find all Collections - ",e); + throw e; + } List collections = new ArrayList(); @@ -351,9 +360,28 @@ public static Collection[] findAll(Context context) throws SQLException */ public static Collection[] findAll(Context context, Integer limit, Integer offset) throws SQLException { - TableRowIterator tri = DatabaseManager.queryTable(context, "collection", - "SELECT * FROM collection ORDER BY name limit ? offset ?", limit, offset); - + TableRowIterator tri = null; + try{ + String query = "SELECT c.* FROM collection c " + + "LEFT JOIN metadatavalue m on (m.resource_id = c.collection_id and m.resource_type_id = ? and m.metadata_field_id = ?) "; + + if(DatabaseManager.isOracle()){ + query += " ORDER BY cast(m.text_value as varchar2(128))"; + }else{ + query += " ORDER BY m.text_value"; + } + query += " limit ? offset ?"; + tri = DatabaseManager.query(context, + query, + Constants.COLLECTION, + MetadataField.findByElement(context, MetadataSchema.find(context, MetadataSchema.DC_SCHEMA).getSchemaID(), "title", null).getFieldID(), + limit, + offset + ); + } catch (SQLException e) { + log.error("Find all Collections offset/limit - ",e); + throw e; + } List collections = new ArrayList(); try @@ -486,10 +514,12 @@ public String getHandle() * @exception IllegalArgumentException * if the requested metadata field doesn't exist */ + @Deprecated public String getMetadata(String field) { - String metadata = collectionRow.getStringColumn(field); - return (metadata == null) ? "" : metadata; + String[] MDValue = getMDValueByLegacyField(field); + String value = getMetadataFirstValue(MDValue[0], MDValue[1], MDValue[2], Item.ANY); + return value == null ? "" : value; } /** @@ -504,10 +534,9 @@ public String getMetadata(String field) * if the requested metadata field doesn't exist * @exception MissingResourceException */ - public void setMetadata(String field, String value) throws MissingResourceException - { - if ((field.trim()).equals("name") - && (value == null || value.trim().equals(""))) + @Deprecated + public void setMetadata(String field, String value) throws MissingResourceException { + if ((field.trim()).equals("name") && (value == null || value.trim().equals(""))) { try { @@ -519,6 +548,8 @@ public void setMetadata(String field, String value) throws MissingResourceExcept } } + String[] MDValue = getMDValueByLegacyField(field); + /* * Set metadata field to null if null * and trim strings to eliminate excess @@ -526,20 +557,21 @@ public void setMetadata(String field, String value) throws MissingResourceExcept */ if(value == null) { - collectionRow.setColumnNull(field); + clearMetadata(MDValue[0], MDValue[1], MDValue[2], Item.ANY); + modifiedMetadata = true; } else { - collectionRow.setColumn(field, value.trim()); + setMetadataSingleValue(MDValue[0], MDValue[1], MDValue[2], null, value); } - modifiedMetadata = true; addDetails(field); } public String getName() { - return getMetadata("name"); + String value = getMetadataFirstValue(MetadataSchema.DC_SCHEMA, "title", null, Item.ANY); + return value == null ? "" : value; } /** @@ -893,8 +925,7 @@ public boolean hasCustomLicense() * @param license * the license, or null */ - public void setLicense(String license) - { + public void setLicense(String license) { setMetadata("license",license); } @@ -1072,10 +1103,7 @@ public void update() throws SQLException, AuthorizeException } if (modifiedMetadata) { - ourContext.addEvent(new Event(Event.MODIFY_METADATA, - Constants.COLLECTION, getID(), getDetails(), - getIdentifiers(ourContext))); - modifiedMetadata = false; + updateMetadata(); clearDetails(); } } @@ -1306,6 +1334,8 @@ void delete() throws SQLException, AuthorizeException, IOException { g.delete(); } + + removeMetadataFromDatabase(); } /** diff --git a/dspace-api/src/main/java/org/dspace/content/Community.java b/dspace-api/src/main/java/org/dspace/content/Community.java index 8a500cc5b78d..bf5c087e552c 100644 --- a/dspace-api/src/main/java/org/dspace/content/Community.java +++ b/dspace-api/src/main/java/org/dspace/content/Community.java @@ -16,10 +16,7 @@ import org.dspace.authorize.ResourcePolicy; import org.dspace.browse.ItemCountException; import org.dspace.browse.ItemCounter; -import org.dspace.core.Constants; -import org.dspace.core.Context; -import org.dspace.core.I18nUtil; -import org.dspace.core.LogManager; +import org.dspace.core.*; import org.dspace.eperson.Group; import org.dspace.event.Event; import org.dspace.handle.HandleManager; @@ -30,9 +27,7 @@ import java.io.IOException; import java.io.InputStream; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import java.util.MissingResourceException; +import java.util.*; /** * Class representing a community @@ -49,9 +44,6 @@ public class Community extends DSpaceObject /** log4j category */ private static Logger log = Logger.getLogger(Community.class); - /** Our context */ - private Context ourContext; - /** The table row corresponding to this item */ private TableRow communityRow; @@ -64,9 +56,6 @@ public class Community extends DSpaceObject /** Flag set when data is modified, for events */ private boolean modified; - /** Flag set when metadata is modified, for events */ - private boolean modifiedMetadata; - /** The default group of administrators */ private Group admins; @@ -86,7 +75,7 @@ public class Community extends DSpaceObject */ Community(Context context, TableRow row) throws SQLException { - ourContext = context; + super(context); communityRow = row; // Get the logo bitstream @@ -107,7 +96,6 @@ public class Community extends DSpaceObject context.cache(this, row.getIntColumn("community_id")); modified = false; - modifiedMetadata = false; admins = groupFromColumn("admin"); @@ -261,8 +249,25 @@ public static Community create(Community parent, Context context, String handle) */ public static Community[] findAll(Context context) throws SQLException { - TableRowIterator tri = DatabaseManager.queryTable(context, "community", - "SELECT * FROM community ORDER BY name"); + TableRowIterator tri = null; + try { + String query = "SELECT c.* FROM community c " + + "LEFT JOIN metadatavalue m on (m.resource_id = c.community_id and m.resource_type_id = ? and m.metadata_field_id = ?) "; + if(DatabaseManager.isOracle()){ + query += " ORDER BY cast(m.text_value as varchar2(128))"; + }else{ + query += " ORDER BY m.text_value"; + } + + tri = DatabaseManager.query(context, + query, + Constants.COMMUNITY, + MetadataField.findByElement(context, MetadataSchema.find(context, MetadataSchema.DC_SCHEMA).getSchemaID(), "title", null).getFieldID() + ); + } catch (SQLException e) { + log.error("Find all Communities - ",e); + throw e; + } List communities = new ArrayList(); @@ -314,10 +319,25 @@ public static Community[] findAll(Context context) throws SQLException public static Community[] findAllTop(Context context) throws SQLException { // get all communities that are not children - TableRowIterator tri = DatabaseManager.queryTable(context, "community", - "SELECT * FROM community WHERE NOT community_id IN " - + "(SELECT child_comm_id FROM community2community) " - + "ORDER BY name"); + TableRowIterator tri = null; + try { + String query = "SELECT c.* FROM community c " + + "LEFT JOIN metadatavalue m on (m.resource_id = c.community_id and m.resource_type_id = ? and m.metadata_field_id = ?) " + + "WHERE NOT c.community_id IN (SELECT child_comm_id FROM community2community) "; + if(DatabaseManager.isOracle()){ + query += " ORDER BY cast(m.text_value as varchar2(128))"; + }else{ + query += " ORDER BY m.text_value"; + } + tri = DatabaseManager.query(context, + query, + Constants.COMMUNITY, + MetadataField.findByElement(context, MetadataSchema.find(context, MetadataSchema.DC_SCHEMA).getSchemaID(), "title", null).getFieldID() + ); + } catch (SQLException e) { + log.error("Find all Top Communities - ",e); + throw e; + } List topCommunities = new ArrayList(); @@ -393,10 +413,12 @@ public String getHandle() * @exception IllegalArgumentException * if the requested metadata field doesn't exist */ + @Deprecated public String getMetadata(String field) { - String metadata = communityRow.getStringColumn(field); - return (metadata == null) ? "" : metadata; + String[] MDValue = getMDValueByLegacyField(field); + String value = getMetadataFirstValue(MDValue[0], MDValue[1], MDValue[2], Item.ANY); + return value == null ? "" : value; } /** @@ -411,9 +433,9 @@ public String getMetadata(String field) * if the requested metadata field doesn't exist * @exception MissingResourceException */ - public void setMetadata(String field, String value)throws MissingResourceException - { - if ((field.trim()).equals("name") + @Deprecated + public void setMetadata(String field, String value) throws MissingResourceException { + if ((field.trim()).equals("name") && (value == null || value.trim().equals(""))) { try @@ -425,28 +447,31 @@ public void setMetadata(String field, String value)throws MissingResourceExcepti value = "Untitled"; } } - - /* - * Set metadata field to null if null + + String[] MDValue = getMDValueByLegacyField(field); + + /* + * Set metadata field to null if null * and trim strings to eliminate excess * whitespace. */ if(value == null) { - communityRow.setColumnNull(field); + clearMetadata(MDValue[0], MDValue[1], MDValue[2], Item.ANY); + modifiedMetadata = true; } else { - communityRow.setColumn(field, value.trim()); + setMetadataSingleValue(MDValue[0], MDValue[1], MDValue[2], null, value); } - - modifiedMetadata = true; + addDetails(field); } public String getName() { - return getMetadata("name"); + String value = getMetadataFirstValue(MetadataSchema.DC_SCHEMA, "title", null, Item.ANY); + return value == null ? "" : value; } /** @@ -536,10 +561,7 @@ public void update() throws SQLException, AuthorizeException } if (modifiedMetadata) { - ourContext.addEvent(new Event(Event.MODIFY_METADATA, - Constants.COMMUNITY, getID(), getDetails(), - getIdentifiers(ourContext))); - modifiedMetadata = false; + updateMetadata(); clearDetails(); } } @@ -629,12 +651,27 @@ public Collection[] getCollections() throws SQLException List collections = new ArrayList(); // Get the table rows - TableRowIterator tri = DatabaseManager.queryTable( - ourContext,"collection", - "SELECT collection.* FROM collection, community2collection WHERE " + - "community2collection.collection_id=collection.collection_id " + - "AND community2collection.community_id= ? ORDER BY collection.name", - getID()); + TableRowIterator tri = null; + try { + String query = "SELECT c.* FROM community2collection c2c, collection c " + + "LEFT JOIN metadatavalue m on (m.resource_id = c.collection_id and m.resource_type_id = ? and m.metadata_field_id = ?) " + + "WHERE c2c.collection_id=c.collection_id AND c2c.community_id=? "; + if(DatabaseManager.isOracle()){ + query += " ORDER BY cast(m.text_value as varchar2(128))"; + }else{ + query += " ORDER BY m.text_value"; + } + tri = DatabaseManager.query( + ourContext, + query, + Constants.COLLECTION, + MetadataField.findByElement(ourContext, MetadataSchema.find(ourContext, MetadataSchema.DC_SCHEMA).getSchemaID(), "title", null).getFieldID(), + getID() + ); + } catch (SQLException e) { + log.error("Find all Collections for this community - ",e); + throw e; + } // Make Collection objects try @@ -685,13 +722,30 @@ public Community[] getSubcommunities() throws SQLException List subcommunities = new ArrayList(); // Get the table rows - TableRowIterator tri = DatabaseManager.queryTable( - ourContext,"community", - "SELECT community.* FROM community, community2community WHERE " + - "community2community.child_comm_id=community.community_id " + - "AND community2community.parent_comm_id= ? ORDER BY community.name", - getID()); - + TableRowIterator tri = null; + try { + String query = "SELECT c.* FROM community2community c2c, community c " + + "LEFT JOIN metadatavalue m on (m.resource_id = c.community_id and m.resource_type_id = ? and m.metadata_field_id = ?) " + + "WHERE c2c.child_comm_id=c.community_id " + + "AND c2c.parent_comm_id= ? "; + if(DatabaseManager.isOracle()){ + query += " ORDER BY cast(m.text_value as varchar2(128))"; + }else{ + query += " ORDER BY m.text_value"; + } + + tri = DatabaseManager.query( + ourContext, + query, + Constants.COMMUNITY, + MetadataField.findByElement(ourContext, MetadataSchema.find(ourContext, MetadataSchema.DC_SCHEMA).getSchemaID(), "title", null).getFieldID(), + getID() + ); + } catch (SQLException e) { + log.error("Find all Sub Communities - ",e); + throw e; + } + // Make Community objects try @@ -1205,6 +1259,9 @@ private void rawDelete() throws SQLException, AuthorizeException, IOException // Remove all associated authorization policies AuthorizeManager.removeAllPolicies(ourContext, this); + // Delete the Dublin Core + removeMetadataFromDatabase(); + // get rid of the content count cache if it exists try { diff --git a/dspace-api/src/main/java/org/dspace/content/DSpaceObject.java b/dspace-api/src/main/java/org/dspace/content/DSpaceObject.java index db96a6851615..e71d554053c7 100644 --- a/dspace-api/src/main/java/org/dspace/content/DSpaceObject.java +++ b/dspace-api/src/main/java/org/dspace/content/DSpaceObject.java @@ -8,13 +8,24 @@ package org.dspace.content; import java.sql.SQLException; +import java.util.*; import org.apache.log4j.Logger; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; import org.dspace.authorize.AuthorizeException; +import org.dspace.content.authority.ChoiceAuthorityManager; +import org.dspace.content.authority.Choices; +import org.dspace.content.authority.MetadataAuthorityManager; import org.dspace.core.Constants; import org.dspace.core.Context; +import org.dspace.core.LogManager; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; +import org.dspace.event.Event; +import org.dspace.storage.rdbms.DatabaseManager; +import org.dspace.storage.rdbms.TableRow; +import org.dspace.storage.rdbms.TableRowIterator; import org.dspace.handle.HandleManager; import org.dspace.identifier.IdentifierService; import org.dspace.utils.DSpace; @@ -24,14 +35,249 @@ */ public abstract class DSpaceObject { + /** Our context */ + protected Context ourContext; + + /** log4j category */ private static final Logger log = Logger.getLogger(DSpaceObject.class); - + + /** + * True if anything else was changed since last update() + * (to drive event mechanism) + */ + protected boolean modifiedMetadata; + + // accumulate information to add to "detail" element of content Event, // e.g. to document metadata fields touched, etc. private StringBuffer eventDetails = null; private String[] identifiers = null; + /** The Dublin Core metadata - inner class for lazy loading */ + protected MetadataCache metadataCache = new MetadataCache(); + + + /** + * Construct a DSpaceOBject with the given table row + * + * @throws SQLException + */ + protected DSpaceObject() + { + modifiedMetadata = false; + } + + protected DSpaceObject(Context context) + { + ourContext = context; + modifiedMetadata = false; + } + + + public void updateMetadata() throws SQLException, AuthorizeException { + // Map counting number of values for each element/qualifier. + // Keys are Strings: "element" or "element.qualifier" + // Values are Integers indicating number of values written for a + // element/qualifier + Map elementCount = new HashMap(); + + modifiedMetadata = false; + + // Arrays to store the working information required + int[] placeNum = new int[getMetadata().size()]; + boolean[] storedDC = new boolean[getMetadata().size()]; + MetadataField[] dcFields = new MetadataField[getMetadata().size()]; + + // Work out the place numbers for the in memory DC + for (int dcIdx = 0; dcIdx < getMetadata().size(); dcIdx++) + { + DCValue dcv = getMetadata().get(dcIdx); + + // Work out the place number for ordering + int current = 0; + + // Key into map is "element" or "element.qualifier" + String key = dcv.element + ((dcv.qualifier == null) ? "" : ("." + dcv.qualifier)); + + Integer currentInteger = elementCount.get(key); + if (currentInteger != null) + { + current = currentInteger.intValue(); + } + + current++; + elementCount.put(key, Integer.valueOf(current)); + + // Store the calculated place number, reset the stored flag, and cache the metadatafield + placeNum[dcIdx] = current; + storedDC[dcIdx] = false; + dcFields[dcIdx] = getMetadataField(dcv); + if (dcFields[dcIdx] == null) + { + // Bad DC field, log and throw exception + log.warn(LogManager + .getHeader(ourContext, "bad_dc", + "Bad DC field. schema=" + dcv.schema + + ", element: \"" + + ((dcv.element == null) ? "null" + : dcv.element) + + "\" qualifier: \"" + + ((dcv.qualifier == null) ? "null" + : dcv.qualifier) + + "\" value: \"" + + ((dcv.value == null) ? "null" + : dcv.value) + "\"" + )); + + throw new SQLException("bad_dublin_core " + + "schema="+dcv.schema+", " + + dcv.element + + " " + dcv.qualifier); + } + } + + // Now the precalculations are done, iterate through the existing metadata + // looking for matches + TableRowIterator tri = retrieveMetadata(); + if (tri != null) + { + try + { + while (tri.hasNext()) + { + TableRow tr = tri.next(); + // Assume that we will remove this row, unless we get a match + boolean removeRow = true; + + // Go through the in-memory metadata, unless we've already decided to keep this row + for (int dcIdx = 0; dcIdx < getMetadata().size() && removeRow; dcIdx++) + { + // Only process if this metadata has not already been matched to something in the DB + if (!storedDC[dcIdx]) + { + boolean matched = true; + DCValue dcv = getMetadata().get(dcIdx); + + // Check the metadata field is the same + if (matched && dcFields[dcIdx].getFieldID() != tr.getIntColumn("metadata_field_id")) + { + matched = false; + } + + // Check the place is the same + if (matched && placeNum[dcIdx] != tr.getIntColumn("place")) + { + matched = false; + } + + // Check the text is the same + if (matched) + { + String text = tr.getStringColumn("text_value"); + if (dcv.value == null && text == null) + { + matched = true; + } + else if (dcv.value != null && dcv.value.equals(text)) + { + matched = true; + } + else + { + matched = false; + } + } + + // Check the language is the same + if (matched) + { + String lang = tr.getStringColumn("text_lang"); + if (dcv.language == null && lang == null) + { + matched = true; + } + else if (dcv.language != null && dcv.language.equals(lang)) + { + matched = true; + } + else + { + matched = false; + } + } + + // check that authority and confidence match + if (matched) + { + String auth = tr.getStringColumn("authority"); + int conf = tr.getIntColumn("confidence"); + if (!((dcv.authority == null && auth == null) || + (dcv.authority != null && auth != null && dcv.authority.equals(auth)) + && dcv.confidence == conf)) + { + matched = false; + } + } + + // If the db record is identical to the in memory values + if (matched) + { + // Flag that the metadata is already in the DB + storedDC[dcIdx] = true; + + // Flag that we are not going to remove the row + removeRow = false; + } + } + } + + // If after processing all the metadata values, we didn't find a match + // delete this row from the DB + if (removeRow) + { + DatabaseManager.delete(ourContext, tr); + modifiedMetadata = true; + } + } + } + finally + { + tri.close(); + } + + + } + + // Add missing in-memory DC + for (int dcIdx = 0; dcIdx < getMetadata().size(); dcIdx++) + { + // Only write values that are not already in the db + if (!storedDC[dcIdx]) + { + DCValue dcv = getMetadata().get(dcIdx); + + // Write DCValue + MetadataValue metadata = new MetadataValue(); + metadata.setResourceId(getID()); + metadata.setResourceTypeId(getType()); + metadata.setFieldId(dcFields[dcIdx].getFieldID()); + metadata.setValue(dcv.value); + metadata.setLanguage(dcv.language); + metadata.setPlace(placeNum[dcIdx]); + metadata.setAuthority(dcv.authority); + metadata.setConfidence(dcv.confidence); + metadata.create(ourContext); + modifiedMetadata = true; + } + } + + if(modifiedMetadata) { + ourContext.addEvent(new Event(Event.MODIFY_METADATA, getType(), getID(), getDetails(), getIdentifiers(ourContext))); + modifiedMetadata = false; + } + } + /** * Reset the cache of event details. */ @@ -242,4 +488,836 @@ public DSpaceObject getParentObject() throws SQLException public abstract void update() throws SQLException, AuthorizeException; public abstract void updateLastModified(); -} + + private TableRowIterator retrieveMetadata() throws SQLException + { + return DatabaseManager.queryTable(ourContext, "MetadataValue", + "SELECT * FROM MetadataValue WHERE resource_id= ? and resource_type_id = ? ORDER BY metadata_field_id, place", + getID(), + getType()); + } + + /** + * Get Dublin Core metadata for the DSpace Object. + * Passing in a null value for qualifier + * or lang only matches Dublin Core fields where that + * qualifier or languages is actually null. + * Passing in DSpaceObject.ANY + * retrieves all metadata fields with any value for the qualifier or + * language, including null + *

+ * Examples: + *

+ * Return values of the unqualified "title" field, in any language. + * Qualified title fields (e.g. "title.uniform") are NOT returned: + *

+ * dspaceobject.getDC( "title", null, DSpaceObject.ANY ); + *

+ * Return all US English values of the "title" element, with any qualifier + * (including unqualified): + *

+ * dspaceobject.getDC( "title", DSpaceObject.ANY, "en_US" ); + *

+ * The ordering of values of a particular element/qualifier/language + * combination is significant. When retrieving with wildcards, values of a + * particular element/qualifier/language combinations will be adjacent, but + * the overall ordering of the combinations is indeterminate. + * + * @param element + * the Dublin Core element. DSpaceObject.ANY matches any + * element. null doesn't really make sense as all + * DC must have an element. + * @param qualifier + * the qualifier. null means unqualified, and + * DSpaceObject.ANY means any qualifier (including + * unqualified.) + * @param lang + * the ISO639 language code, optionally followed by an underscore + * and the ISO3166 country code. null means only + * values with no language are returned, and + * DSpaceObject.ANY means values with any country code or + * no country code are returned. + * @return Dublin Core fields that match the parameters + */ + @Deprecated + public DCValue[] getDC(String element, String qualifier, String lang) + { + return getMetadata(MetadataSchema.DC_SCHEMA, element, qualifier, lang); + } + + /** + * Get metadata for the DSpace Object in a chosen schema. + * See MetadataSchema for more information about schemas. + * Passing in a null value for qualifier + * or lang only matches metadata fields where that + * qualifier or languages is actually null. + * Passing in DSpaceObject.ANY + * retrieves all metadata fields with any value for the qualifier or + * language, including null + *

+ * Examples: + *

+ * Return values of the unqualified "title" field, in any language. + * Qualified title fields (e.g. "title.uniform") are NOT returned: + *

+ * dspaceobject.getMetadataByMetadataString("dc", "title", null, DSpaceObject.ANY ); + *

+ * Return all US English values of the "title" element, with any qualifier + * (including unqualified): + *

+ * dspaceobject.getMetadataByMetadataString("dc, "title", DSpaceObject.ANY, "en_US" ); + *

+ * The ordering of values of a particular element/qualifier/language + * combination is significant. When retrieving with wildcards, values of a + * particular element/qualifier/language combinations will be adjacent, but + * the overall ordering of the combinations is indeterminate. + * + * @param schema + * the schema for the metadata field. Must match + * the name of an existing metadata schema. + * @param element + * the element name. DSpaceObject.ANY matches any + * element. null doesn't really make sense as all + * metadata must have an element. + * @param qualifier + * the qualifier. null means unqualified, and + * DSpaceObject.ANY means any qualifier (including + * unqualified.) + * @param lang + * the ISO639 language code, optionally followed by an underscore + * and the ISO3166 country code. null means only + * values with no language are returned, and + * DSpaceObject.ANY means values with any country code or + * no country code are returned. + * @return metadata fields that match the parameters + */ + public DCValue[] getMetadata(String schema, String element, String qualifier, + String lang) + { + // Build up list of matching values + List values = new ArrayList(); + for (DCValue dcv : getMetadata()) + { + if (match(schema, element, qualifier, lang, dcv)) + { + // We will return a copy of the object in case it is altered + DCValue copy = new DCValue(); + copy.element = dcv.element; + copy.qualifier = dcv.qualifier; + copy.value = dcv.value; + copy.language = dcv.language; + copy.schema = dcv.schema; + copy.authority = dcv.authority; + copy.confidence = dcv.confidence; + values.add(copy); + } + } + + // Create an array of matching values + DCValue[] valueArray = new DCValue[values.size()]; + valueArray = (DCValue[]) values.toArray(valueArray); + + return valueArray; + } + + /** + * Retrieve metadata field values from a given metadata string + * of the form .[.|.*] + * + * @param mdString + * The metadata string of the form + * .[.|.*] + */ + public DCValue[] getMetadataByMetadataString(String mdString) + { + StringTokenizer dcf = new StringTokenizer(mdString, "."); + + String[] tokens = { "", "", "" }; + int i = 0; + while(dcf.hasMoreTokens()) + { + tokens[i] = dcf.nextToken().trim(); + i++; + } + String schema = tokens[0]; + String element = tokens[1]; + String qualifier = tokens[2]; + + DCValue[] values; + if ("*".equals(qualifier)) + { + values = getMetadata(schema, element, Item.ANY, Item.ANY); + } + else if ("".equals(qualifier)) + { + values = getMetadata(schema, element, null, Item.ANY); + } + else + { + values = getMetadata(schema, element, qualifier, Item.ANY); + } + + return values; + } + + /** + * Retrieve first metadata field value + */ + protected String getMetadataFirstValue(String schema, String element, String qualifier, String language){ + DCValue[] dcvalues = getMetadata(schema, element, qualifier, Item.ANY); + if(dcvalues.length>0){ + return dcvalues[0].value; + } + return null; + } + + /** + * Set first metadata field value + */ + protected void setMetadataSingleValue(String schema, String element, String qualifier, String language, String value) { + if(value != null) + { + clearMetadata(schema, element, qualifier, language); + addMetadata(schema, element, qualifier, language, value); + modifiedMetadata = true; + } + } + + protected List getMetadata() + { + try + { + return metadataCache.get(ourContext, getID(), getType(), log); + } + catch (SQLException e) + { + log.error("Loading item - cannot load metadata"); + } + + return new ArrayList(); + } + + /** + * Get the value of a metadata field + * + * @param value + * the name of the metadata field to get + * + * @return the value of the metadata field (or null if the column is an SQL NULL) + * + * @exception IllegalArgumentException + * if the requested metadata field doesn't exist + */ + public String getMetadata(String value){ + DCValue[] dcvalues = getMetadataByMetadataString(value); + + if(dcvalues.length>0) { + return dcvalues[0].toString(); + } + return null; + } + + /** + * Add Dublin Core metadata fields. These are appended to existing values. + * Use clearDC to remove values. The ordering of values + * passed in is maintained. + * + * @param element + * the Dublin Core element + * @param qualifier + * the Dublin Core qualifier, or null for + * unqualified + * @param lang + * the ISO639 language code, optionally followed by an underscore + * and the ISO3166 country code. null means the + * value has no language (for example, a date). + * @param values + * the values to add. + */ + @Deprecated + public void addDC(String element, String qualifier, String lang, + String[] values) + { + addMetadata(MetadataSchema.DC_SCHEMA, element, qualifier, lang, values); + } + + /** + * Add a single Dublin Core metadata field. This is appended to existing + * values. Use clearDC to remove values. + * + * @param element + * the Dublin Core element + * @param qualifier + * the Dublin Core qualifier, or null for + * unqualified + * @param lang + * the ISO639 language code, optionally followed by an underscore + * and the ISO3166 country code. null means the + * value has no language (for example, a date). + * @param value + * the value to add. + */ + @Deprecated + public void addDC(String element, String qualifier, String lang, + String value) + { + addMetadata(MetadataSchema.DC_SCHEMA, element, qualifier, lang, value); + } + + /** + * Add metadata fields. These are appended to existing values. + * Use clearDC to remove values. The ordering of values + * passed in is maintained. + *

+ * If metadata authority control is available, try to get authority + * values. The authority confidence depends on whether authority is + * required or not. + * @param schema + * the schema for the metadata field. Must match + * the name of an existing metadata schema. + * @param element + * the metadata element name + * @param qualifier + * the metadata qualifier name, or null for + * unqualified + * @param lang + * the ISO639 language code, optionally followed by an underscore + * and the ISO3166 country code. null means the + * value has no language (for example, a date). + * @param values + * the values to add. + */ + public void addMetadata(String schema, String element, String qualifier, String lang, + String[] values) + { + MetadataAuthorityManager mam = MetadataAuthorityManager.getManager(); + String fieldKey = MetadataAuthorityManager.makeFieldKey(schema, element, qualifier); + if (mam.isAuthorityControlled(fieldKey)) + { + String authorities[] = new String[values.length]; + int confidences[] = new int[values.length]; + for (int i = 0; i < values.length; ++i) + { + getAuthoritiesAndConfidences(fieldKey, values, authorities, confidences, i); + } + addMetadata(schema, element, qualifier, lang, values, authorities, confidences); + } + else + { + addMetadata(schema, element, qualifier, lang, values, null, null); + } + } + + protected void getAuthoritiesAndConfidences(String fieldKey, String[] values, String[] authorities, int[] confidences, int i) { + Choices c = ChoiceAuthorityManager.getManager().getBestMatch(fieldKey, values[i], -1, null); + authorities[i] = c.values.length > 0 ? c.values[0].authority : null; + confidences[i] = c.confidence; + } + + /** + * Add metadata fields. These are appended to existing values. + * Use clearDC to remove values. The ordering of values + * passed in is maintained. + * @param schema + * the schema for the metadata field. Must match + * the name of an existing metadata schema. + * @param element + * the metadata element name + * @param qualifier + * the metadata qualifier name, or null for + * unqualified + * @param lang + * the ISO639 language code, optionally followed by an underscore + * and the ISO3166 country code. null means the + * value has no language (for example, a date). + * @param values + * the values to add. + * @param authorities + * the external authority key for this value (or null) + * @param confidences + * the authority confidence (default 0) + */ + public void addMetadata(String schema, String element, String qualifier, String lang, + String[] values, String authorities[], int confidences[]) + { + List dublinCore = getMetadata(); + MetadataAuthorityManager mam = MetadataAuthorityManager.getManager(); + boolean authorityControlled = mam.isAuthorityControlled(schema, element, qualifier); + boolean authorityRequired = mam.isAuthorityRequired(schema, element, qualifier); + String fieldName = schema+"."+element+((qualifier==null)? "": "."+qualifier); + + // We will not verify that they are valid entries in the registry + // until update() is called. + for (int i = 0; i < values.length; i++) + { + DCValue dcv = new DCValue(); + dcv.schema = schema; + dcv.element = element; + dcv.qualifier = qualifier; + dcv.language = (lang == null ? null : lang.trim()); + + // Logic to set Authority and Confidence: + // - normalize an empty string for authority to NULL. + // - if authority key is present, use given confidence or NOVALUE if not given + // - otherwise, preserve confidence if meaningful value was given since it may document a failed authority lookup + // - CF_UNSET signifies no authority nor meaningful confidence. + // - it's possible to have empty authority & CF_ACCEPTED if e.g. user deletes authority key + if (authorityControlled) + { + if (authorities != null && authorities[i] != null && authorities[i].length() > 0) + { + dcv.authority = authorities[i]; + dcv.confidence = confidences == null ? Choices.CF_NOVALUE : confidences[i]; + } + else + { + dcv.authority = null; + dcv.confidence = confidences == null ? Choices.CF_UNSET : confidences[i]; + } + // authority sanity check: if authority is required, was it supplied? + // XXX FIXME? can't throw a "real" exception here without changing all the callers to expect it, so use a runtime exception + if (authorityRequired && (dcv.authority == null || dcv.authority.length() == 0)) + { + throw new IllegalArgumentException("The metadata field \"" + fieldName + "\" requires an authority key but none was provided. Vaue=\"" + dcv.value + "\""); + } + } + if (values[i] != null) + { + // remove control unicode char + String temp = values[i].trim(); + char[] dcvalue = temp.toCharArray(); + for (int charPos = 0; charPos < dcvalue.length; charPos++) + { + if (Character.isISOControl(dcvalue[charPos]) && + !String.valueOf(dcvalue[charPos]).equals("\u0009") && + !String.valueOf(dcvalue[charPos]).equals("\n") && + !String.valueOf(dcvalue[charPos]).equals("\r")) + { + dcvalue[charPos] = ' '; + } + } + dcv.value = String.valueOf(dcvalue); + } + else + { + dcv.value = null; + } + dublinCore.add(dcv); + addDetails(fieldName); + } + + if (values.length > 0) + { + modifiedMetadata = true; + } + } + + /** + * Add a single metadata field. This is appended to existing + * values. Use clearDC to remove values. + * + * @param schema + * the schema for the metadata field. Must match + * the name of an existing metadata schema. + * @param element + * the metadata element name + * @param qualifier + * the metadata qualifier, or null for + * unqualified + * @param lang + * the ISO639 language code, optionally followed by an underscore + * and the ISO3166 country code. null means the + * value has no language (for example, a date). + * @param value + * the value to add. + */ + public void addMetadata(String schema, String element, String qualifier, + String lang, String value) + { + String[] valArray = new String[1]; + valArray[0] = value; + + addMetadata(schema, element, qualifier, lang, valArray); + } + + /** + * Add a single metadata field. This is appended to existing + * values. Use clearDC to remove values. + * + * @param schema + * the schema for the metadata field. Must match + * the name of an existing metadata schema. + * @param element + * the metadata element name + * @param qualifier + * the metadata qualifier, or null for + * unqualified + * @param lang + * the ISO639 language code, optionally followed by an underscore + * and the ISO3166 country code. null means the + * value has no language (for example, a date). + * @param value + * the value to add. + * @param authority + * the external authority key for this value (or null) + * @param confidence + * the authority confidence (default 0) + */ + public void addMetadata(String schema, String element, String qualifier, + String lang, String value, String authority, int confidence) + { + String[] valArray = new String[1]; + String[] authArray = new String[1]; + int[] confArray = new int[1]; + valArray[0] = value; + authArray[0] = authority; + confArray[0] = confidence; + + addMetadata(schema, element, qualifier, lang, valArray, authArray, confArray); + } + + /** + * Clear Dublin Core metadata values. As with getDC above, + * passing in null only matches fields where the qualifier or + * language is actually null.Item.ANY will + * match any element, qualifier or language, including null. + * Thus, idspaceobject.clearDC(DSpaceObject.ANY, DSpaceObject.ANY, DSpaceObject.ANY) will + * remove all Dublin Core metadata associated with an DSpaceObject. + * + * @param element + * the Dublin Core element to remove, or Item.ANY + * @param qualifier + * the qualifier. null means unqualified, and + * Item.ANY means any qualifier (including + * unqualified.) + * @param lang + * the ISO639 language code, optionally followed by an underscore + * and the ISO3166 country code. null means only + * values with no language are removed, and Item.ANY + * means values with any country code or no country code are + * removed. + */ + @Deprecated + public void clearDC(String element, String qualifier, String lang) + { + clearMetadata(MetadataSchema.DC_SCHEMA, element, qualifier, lang); + } + + /** + * Clear metadata values. As with getDC above, + * passing in null only matches fields where the qualifier or + * language is actually null.Item.ANY will + * match any element, qualifier or language, including null. + * Thus, dspaceobject.clearDC(Item.ANY, Item.ANY, Item.ANY) will + * remove all Dublin Core metadata associated with an DSpaceObject. + * + * @param schema + * the schema for the metadata field. Must match + * the name of an existing metadata schema. + * @param element + * the Dublin Core element to remove, or Item.ANY + * @param qualifier + * the qualifier. null means unqualified, and + * Item.ANY means any qualifier (including + * unqualified.) + * @param lang + * the ISO639 language code, optionally followed by an underscore + * and the ISO3166 country code. null means only + * values with no language are removed, and Item.ANY + * means values with any country code or no country code are + * removed. + */ + public void clearMetadata(String schema, String element, String qualifier, + String lang) + { + // We will build a list of values NOT matching the values to clear + List values = new ArrayList(); + for (DCValue dcv : getMetadata()) + { + if (!match(schema, element, qualifier, lang, dcv)) + { + values.add(dcv); + } + } + + // Now swap the old list of values for the new, unremoved values + setMetadata(values); + modifiedMetadata = true; + } + + /** + * Utility method for pattern-matching metadata elements. This + * method will return true if the given schema, + * element, qualifier and language match the schema, element, + * qualifier and language of the DCValue object passed + * in. Any or all of the element, qualifier and language passed + * in can be the Item.ANY wildcard. + * + * @param schema + * the schema for the metadata field. Must match + * the name of an existing metadata schema. + * @param element + * the element to match, or Item.ANY + * @param qualifier + * the qualifier to match, or Item.ANY + * @param language + * the language to match, or Item.ANY + * @param dcv + * the Dublin Core value + * @return true if there is a match + */ + private boolean match(String schema, String element, String qualifier, + String language, DCValue dcv) + { + // We will attempt to disprove a match - if we can't we have a match + if (!element.equals(Item.ANY) && !element.equals(dcv.element)) + { + // Elements do not match, no wildcard + return false; + } + + if (qualifier == null) + { + // Value must be unqualified + if (dcv.qualifier != null) + { + // Value is qualified, so no match + return false; + } + } + else if (!qualifier.equals(Item.ANY)) + { + // Not a wildcard, so qualifier must match exactly + if (!qualifier.equals(dcv.qualifier)) + { + return false; + } + } + + if (language == null) + { + // Value must be null language to match + if (dcv.language != null) + { + // Value is qualified, so no match + return false; + } + } + else if (!language.equals(Item.ANY)) + { + // Not a wildcard, so language must match exactly + if (!language.equals(dcv.language)) + { + return false; + } + } + + if (!schema.equals(Item.ANY)) + { + if (dcv.schema != null && !dcv.schema.equals(schema)) + { + // The namespace doesn't match + return false; + } + } + + // If we get this far, we have a match + return true; + } + + protected transient MetadataField[] allMetadataFields = null; + protected MetadataField getMetadataField(DCValue dcv) throws SQLException, AuthorizeException + { + if (allMetadataFields == null) + { + allMetadataFields = MetadataField.findAll(ourContext); + } + + if (allMetadataFields != null) + { + int schemaID = getMetadataSchemaID(dcv); + for (MetadataField field : allMetadataFields) + { + if (field.getSchemaID() == schemaID && + StringUtils.equals(field.getElement(), dcv.element) && + StringUtils.equals(field.getQualifier(), dcv.qualifier)) + { + return field; + } + } + } + + return null; + } + + private int getMetadataSchemaID(DCValue dcv) throws SQLException + { + int schemaID; + MetadataSchema schema = MetadataSchema.find(ourContext,dcv.schema); + if (schema == null) + { + schemaID = MetadataSchema.DC_SCHEMA_ID; + } + else + { + schemaID = schema.getSchemaID(); + } + return schemaID; + } + + /** + * Utility method to remove all descriptive metadata associated with the DSpaceObject from + * the database (regardless of in-memory version) + * + * @throws SQLException + */ + protected void removeMetadataFromDatabase() throws SQLException + { + DatabaseManager.updateQuery(ourContext, + "DELETE FROM MetadataValue WHERE resource_id= ? and resource_type_id=?", + getID(), + getType()); + } + + private void setMetadata(List metadata) + { + metadataCache.set(metadata); + modifiedMetadata = true; + } + + class MetadataCache + { + List metadata = null; + + List get(Context c, int resourceId, int resourceTypeId, Logger log) throws SQLException + { + if (metadata == null) + { + metadata = new ArrayList(); + + // Get Dublin Core metadata + TableRowIterator tri = retrieveMetadata(resourceId, resourceTypeId); + + if (tri != null) + { + try + { + while (tri.hasNext()) + { + TableRow resultRow = tri.next(); + + // Get the associated metadata field and schema information + int fieldID = resultRow.getIntColumn("metadata_field_id"); + MetadataField field = MetadataField.find(c, fieldID); + + if (field == null) + { + log.error("Loading item - cannot find metadata field " + fieldID); + } + else + { + MetadataSchema schema = MetadataSchema.find(c, field.getSchemaID()); + if (schema == null) + { + log.error("Loading item - cannot find metadata schema " + field.getSchemaID() + ", field " + fieldID); + } + else + { + // Make a DCValue object + DCValue dcv = new DCValue(); + dcv.element = field.getElement(); + dcv.qualifier = field.getQualifier(); + dcv.value = resultRow.getStringColumn("text_value"); + dcv.language = resultRow.getStringColumn("text_lang"); + //dcv.namespace = schema.getNamespace(); + dcv.schema = schema.getName(); + dcv.authority = resultRow.getStringColumn("authority"); + dcv.confidence = resultRow.getIntColumn("confidence"); + + // Add it to the list + metadata.add(dcv); + } + } + } + } + finally + { + // close the TableRowIterator to free up resources + if (tri != null) + { + tri.close(); + } + } + } + } + + return metadata; + } + + void set(List m) + { + metadata = m; + } + + TableRowIterator retrieveMetadata(int resourceId, int resourceTypeId) throws SQLException + { + return DatabaseManager.queryTable(ourContext, "MetadataValue", + "SELECT * FROM MetadataValue WHERE resource_id= ? and resource_type_id = ? ORDER BY metadata_field_id, place", + resourceId, + resourceTypeId); + } + } + + protected String[] getMDValueByField(String field){ + StringTokenizer dcf = new StringTokenizer(field, "."); + + String[] tokens = { "", "", "" }; + int i = 0; + while(dcf.hasMoreTokens()){ + tokens[i] = dcf.nextToken().trim(); + i++; + } + + if(i!=0){ + return tokens; + }else{ + return getMDValueByLegacyField(field); + } + } + + protected String[] getMDValueByLegacyField(String field){ + switch (field) { + case "introductory_text": + return new String[]{MetadataSchema.DC_SCHEMA, "description", null}; + case "short_description": + return new String[]{MetadataSchema.DC_SCHEMA, "description", "abstract"}; + case "side_bar_text": + return new String[]{MetadataSchema.DC_SCHEMA, "description", "tableofcontents"}; + case "copyright_text": + return new String[]{MetadataSchema.DC_SCHEMA, "rights", null}; + case "name": + return new String[]{MetadataSchema.DC_SCHEMA, "title", null}; + case "provenance_description": + return new String[]{MetadataSchema.DC_SCHEMA,"provenance", null}; + case "license": + return new String[]{MetadataSchema.DC_SCHEMA, "rights", "license"}; + case "user_format_description": + return new String[]{MetadataSchema.DC_SCHEMA,"format",null}; + case "source": + return new String[]{MetadataSchema.DC_SCHEMA,"source",null}; + case "firstname": + return new String[]{"eperson","firstname",null}; + case "lastname": + return new String[]{"eperson","lastname",null}; + case "phone": + return new String[]{"eperson","phone",null}; + case "netid": + return new String[]{"eperson","netid",null}; + case "language": + return new String[]{"eperson","language",null}; + default: + return new String[]{null, null, null}; + } + } + +} \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/content/Item.java b/dspace-api/src/main/java/org/dspace/content/Item.java index 7c5dcac21075..6dee7aeff531 100644 --- a/dspace-api/src/main/java/org/dspace/content/Item.java +++ b/dspace-api/src/main/java/org/dspace/content/Item.java @@ -14,12 +14,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Date; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; -import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.dspace.app.util.AuthorizeUtil; import org.dspace.authorize.AuthorizeConfiguration; @@ -33,7 +29,6 @@ import org.dspace.core.LogManager; import org.dspace.content.authority.Choices; import org.dspace.content.authority.ChoiceAuthorityManager; -import org.dspace.content.authority.MetadataAuthorityManager; import org.dspace.event.Event; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; @@ -70,9 +65,6 @@ public class Item extends DSpaceObject /** log4j category */ private static final Logger log = Logger.getLogger(Item.class); - /** Our context */ - private Context ourContext; - /** The table row corresponding to this item */ private TableRow itemRow; @@ -82,18 +74,10 @@ public class Item extends DSpaceObject /** The bundles in this item - kept in sync with DB */ private List bundles; - /** The Dublin Core metadata - inner class for lazy loading */ - MetadataCache dublinCore = new MetadataCache(); /** Handle, if any */ private String handle; - /** - * True if the Dublin Core has changed since reading from the DB or the last - * update() - */ - private boolean dublinCoreChanged; - /** * True if anything else was changed since last update() * (to drive event mechanism) @@ -111,9 +95,8 @@ public class Item extends DSpaceObject */ Item(Context context, TableRow row) throws SQLException { - ourContext = context; + super(context); itemRow = row; - dublinCoreChanged = false; modified = false; clearDetails(); @@ -124,12 +107,6 @@ public class Item extends DSpaceObject context.cache(this, row.getIntColumn("item_id")); } - private TableRowIterator retrieveMetadata() throws SQLException - { - return DatabaseManager.queryTable(ourContext, "MetadataValue", - "SELECT * FROM MetadataValue WHERE item_id= ? ORDER BY metadata_field_id, place", - itemRow.getIntColumn("item_id")); - } /** * Get an item from the database. The item, its Dublin Core metadata, and @@ -425,573 +402,6 @@ private int getOwningCollectionID() return itemRow.getIntColumn("owning_collection"); } - /** - * Get Dublin Core metadata for the item. - * Passing in a null value for qualifier - * or lang only matches Dublin Core fields where that - * qualifier or languages is actually null. - * Passing in Item.ANY - * retrieves all metadata fields with any value for the qualifier or - * language, including null - *

- * Examples: - *

- * Return values of the unqualified "title" field, in any language. - * Qualified title fields (e.g. "title.uniform") are NOT returned: - *

- * item.getDC( "title", null, Item.ANY ); - *

- * Return all US English values of the "title" element, with any qualifier - * (including unqualified): - *

- * item.getDC( "title", Item.ANY, "en_US" ); - *

- * The ordering of values of a particular element/qualifier/language - * combination is significant. When retrieving with wildcards, values of a - * particular element/qualifier/language combinations will be adjacent, but - * the overall ordering of the combinations is indeterminate. - * - * @param element - * the Dublin Core element. Item.ANY matches any - * element. null doesn't really make sense as all - * DC must have an element. - * @param qualifier - * the qualifier. null means unqualified, and - * Item.ANY means any qualifier (including - * unqualified.) - * @param lang - * the ISO639 language code, optionally followed by an underscore - * and the ISO3166 country code. null means only - * values with no language are returned, and - * Item.ANY means values with any country code or - * no country code are returned. - * @return Dublin Core fields that match the parameters - */ - @Deprecated - public DCValue[] getDC(String element, String qualifier, String lang) - { - return getMetadata(MetadataSchema.DC_SCHEMA, element, qualifier, lang); - } - - /** - * Get metadata for the item in a chosen schema. - * See MetadataSchema for more information about schemas. - * Passing in a null value for qualifier - * or lang only matches metadata fields where that - * qualifier or languages is actually null. - * Passing in Item.ANY - * retrieves all metadata fields with any value for the qualifier or - * language, including null - *

- * Examples: - *

- * Return values of the unqualified "title" field, in any language. - * Qualified title fields (e.g. "title.uniform") are NOT returned: - *

- * item.getMetadata("dc", "title", null, Item.ANY ); - *

- * Return all US English values of the "title" element, with any qualifier - * (including unqualified): - *

- * item.getMetadata("dc, "title", Item.ANY, "en_US" ); - *

- * The ordering of values of a particular element/qualifier/language - * combination is significant. When retrieving with wildcards, values of a - * particular element/qualifier/language combinations will be adjacent, but - * the overall ordering of the combinations is indeterminate. - * - * @param schema - * the schema for the metadata field. Must match - * the name of an existing metadata schema. - * @param element - * the element name. Item.ANY matches any - * element. null doesn't really make sense as all - * metadata must have an element. - * @param qualifier - * the qualifier. null means unqualified, and - * Item.ANY means any qualifier (including - * unqualified.) - * @param lang - * the ISO639 language code, optionally followed by an underscore - * and the ISO3166 country code. null means only - * values with no language are returned, and - * Item.ANY means values with any country code or - * no country code are returned. - * @return metadata fields that match the parameters - */ - public DCValue[] getMetadata(String schema, String element, String qualifier, - String lang) - { - // Build up list of matching values - List values = new ArrayList(); - for (DCValue dcv : getMetadata()) - { - if (match(schema, element, qualifier, lang, dcv)) - { - // We will return a copy of the object in case it is altered - DCValue copy = new DCValue(); - copy.element = dcv.element; - copy.qualifier = dcv.qualifier; - copy.value = dcv.value; - copy.language = dcv.language; - copy.schema = dcv.schema; - copy.authority = dcv.authority; - copy.confidence = dcv.confidence; - values.add(copy); - } - } - - // Create an array of matching values - DCValue[] valueArray = new DCValue[values.size()]; - valueArray = (DCValue[]) values.toArray(valueArray); - - return valueArray; - } - - /** - * Retrieve metadata field values from a given metadata string - * of the form .[.|.*] - * - * @param mdString - * The metadata string of the form - * .[.|.*] - */ - public DCValue[] getMetadata(String mdString) - { - StringTokenizer dcf = new StringTokenizer(mdString, "."); - - String[] tokens = { "", "", "" }; - int i = 0; - while(dcf.hasMoreTokens()) - { - tokens[i] = dcf.nextToken().trim(); - i++; - } - String schema = tokens[0]; - String element = tokens[1]; - String qualifier = tokens[2]; - - DCValue[] values; - if ("*".equals(qualifier)) - { - values = getMetadata(schema, element, Item.ANY, Item.ANY); - } - else if ("".equals(qualifier)) - { - values = getMetadata(schema, element, null, Item.ANY); - } - else - { - values = getMetadata(schema, element, qualifier, Item.ANY); - } - - return values; - } - - /** - * Add Dublin Core metadata fields. These are appended to existing values. - * Use clearDC to remove values. The ordering of values - * passed in is maintained. - * - * @param element - * the Dublin Core element - * @param qualifier - * the Dublin Core qualifier, or null for - * unqualified - * @param lang - * the ISO639 language code, optionally followed by an underscore - * and the ISO3166 country code. null means the - * value has no language (for example, a date). - * @param values - * the values to add. - */ - @Deprecated - public void addDC(String element, String qualifier, String lang, - String[] values) - { - addMetadata(MetadataSchema.DC_SCHEMA, element, qualifier, lang, values); - } - - /** - * Add a single Dublin Core metadata field. This is appended to existing - * values. Use clearDC to remove values. - * - * @param element - * the Dublin Core element - * @param qualifier - * the Dublin Core qualifier, or null for - * unqualified - * @param lang - * the ISO639 language code, optionally followed by an underscore - * and the ISO3166 country code. null means the - * value has no language (for example, a date). - * @param value - * the value to add. - */ - @Deprecated - public void addDC(String element, String qualifier, String lang, - String value) - { - addMetadata(MetadataSchema.DC_SCHEMA, element, qualifier, lang, value); - } - - /** - * Add metadata fields. These are appended to existing values. - * Use clearDC to remove values. The ordering of values - * passed in is maintained. - *

- * If metadata authority control is available, try to get authority - * values. The authority confidence depends on whether authority is - * required or not. - * @param schema - * the schema for the metadata field. Must match - * the name of an existing metadata schema. - * @param element - * the metadata element name - * @param qualifier - * the metadata qualifier name, or null for - * unqualified - * @param lang - * the ISO639 language code, optionally followed by an underscore - * and the ISO3166 country code. null means the - * value has no language (for example, a date). - * @param values - * the values to add. - */ - public void addMetadata(String schema, String element, String qualifier, String lang, - String[] values) - { - MetadataAuthorityManager mam = MetadataAuthorityManager.getManager(); - String fieldKey = MetadataAuthorityManager.makeFieldKey(schema, element, qualifier); - if (mam.isAuthorityControlled(fieldKey)) - { - String authorities[] = new String[values.length]; - int confidences[] = new int[values.length]; - for (int i = 0; i < values.length; ++i) - { - Choices c = ChoiceAuthorityManager.getManager().getBestMatch(fieldKey, values[i], getOwningCollectionID(), null); - authorities[i] = c.values.length > 0 ? c.values[0].authority : null; - confidences[i] = c.confidence; - } - addMetadata(schema, element, qualifier, lang, values, authorities, confidences); - } - else - { - addMetadata(schema, element, qualifier, lang, values, null, null); - } - } - - /** - * Add metadata fields. These are appended to existing values. - * Use clearDC to remove values. The ordering of values - * passed in is maintained. - * @param schema - * the schema for the metadata field. Must match - * the name of an existing metadata schema. - * @param element - * the metadata element name - * @param qualifier - * the metadata qualifier name, or null for - * unqualified - * @param lang - * the ISO639 language code, optionally followed by an underscore - * and the ISO3166 country code. null means the - * value has no language (for example, a date). - * @param values - * the values to add. - * @param authorities - * the external authority key for this value (or null) - * @param confidences - * the authority confidence (default 0) - */ - public void addMetadata(String schema, String element, String qualifier, String lang, - String[] values, String authorities[], int confidences[]) - { - List dublinCore = getMetadata(); - MetadataAuthorityManager mam = MetadataAuthorityManager.getManager(); - boolean authorityControlled = mam.isAuthorityControlled(schema, element, qualifier); - boolean authorityRequired = mam.isAuthorityRequired(schema, element, qualifier); - String fieldName = schema+"."+element+((qualifier==null)? "": "."+qualifier); - - // We will not verify that they are valid entries in the registry - // until update() is called. - for (int i = 0; i < values.length; i++) - { - DCValue dcv = new DCValue(); - dcv.schema = schema; - dcv.element = element; - dcv.qualifier = qualifier; - dcv.language = (lang == null ? null : lang.trim()); - - // Logic to set Authority and Confidence: - // - normalize an empty string for authority to NULL. - // - if authority key is present, use given confidence or NOVALUE if not given - // - otherwise, preserve confidence if meaningful value was given since it may document a failed authority lookup - // - CF_UNSET signifies no authority nor meaningful confidence. - // - it's possible to have empty authority & CF_ACCEPTED if e.g. user deletes authority key - if (authorityControlled) - { - if (authorities != null && authorities[i] != null && authorities[i].length() > 0) - { - dcv.authority = authorities[i]; - dcv.confidence = confidences == null ? Choices.CF_NOVALUE : confidences[i]; - } - else - { - dcv.authority = null; - dcv.confidence = confidences == null ? Choices.CF_UNSET : confidences[i]; - } - // authority sanity check: if authority is required, was it supplied? - // XXX FIXME? can't throw a "real" exception here without changing all the callers to expect it, so use a runtime exception - if (authorityRequired && (dcv.authority == null || dcv.authority.length() == 0)) - { - throw new IllegalArgumentException("The metadata field \"" + fieldName + "\" requires an authority key but none was provided. Vaue=\"" + dcv.value + "\""); - } - } - if (values[i] != null) - { - // remove control unicode char - String temp = values[i].trim(); - char[] dcvalue = temp.toCharArray(); - for (int charPos = 0; charPos < dcvalue.length; charPos++) - { - if (Character.isISOControl(dcvalue[charPos]) && - !String.valueOf(dcvalue[charPos]).equals("\u0009") && - !String.valueOf(dcvalue[charPos]).equals("\n") && - !String.valueOf(dcvalue[charPos]).equals("\r")) - { - dcvalue[charPos] = ' '; - } - } - dcv.value = String.valueOf(dcvalue); - } - else - { - dcv.value = null; - } - dublinCore.add(dcv); - addDetails(fieldName); - } - - if (values.length > 0) - { - dublinCoreChanged = true; - } - } - - /** - * Add a single metadata field. This is appended to existing - * values. Use clearDC to remove values. - * - * @param schema - * the schema for the metadata field. Must match - * the name of an existing metadata schema. - * @param element - * the metadata element name - * @param qualifier - * the metadata qualifier, or null for - * unqualified - * @param lang - * the ISO639 language code, optionally followed by an underscore - * and the ISO3166 country code. null means the - * value has no language (for example, a date). - * @param value - * the value to add. - */ - public void addMetadata(String schema, String element, String qualifier, - String lang, String value) - { - String[] valArray = new String[1]; - valArray[0] = value; - - addMetadata(schema, element, qualifier, lang, valArray); - } - - /** - * Add a single metadata field. This is appended to existing - * values. Use clearDC to remove values. - * - * @param schema - * the schema for the metadata field. Must match - * the name of an existing metadata schema. - * @param element - * the metadata element name - * @param qualifier - * the metadata qualifier, or null for - * unqualified - * @param lang - * the ISO639 language code, optionally followed by an underscore - * and the ISO3166 country code. null means the - * value has no language (for example, a date). - * @param value - * the value to add. - * @param authority - * the external authority key for this value (or null) - * @param confidence - * the authority confidence (default 0) - */ - public void addMetadata(String schema, String element, String qualifier, - String lang, String value, String authority, int confidence) - { - String[] valArray = new String[1]; - String[] authArray = new String[1]; - int[] confArray = new int[1]; - valArray[0] = value; - authArray[0] = authority; - confArray[0] = confidence; - - addMetadata(schema, element, qualifier, lang, valArray, authArray, confArray); - } - - /** - * Clear Dublin Core metadata values. As with getDC above, - * passing in null only matches fields where the qualifier or - * language is actually null.Item.ANY will - * match any element, qualifier or language, including null. - * Thus, item.clearDC(Item.ANY, Item.ANY, Item.ANY) will - * remove all Dublin Core metadata associated with an item. - * - * @param element - * the Dublin Core element to remove, or Item.ANY - * @param qualifier - * the qualifier. null means unqualified, and - * Item.ANY means any qualifier (including - * unqualified.) - * @param lang - * the ISO639 language code, optionally followed by an underscore - * and the ISO3166 country code. null means only - * values with no language are removed, and Item.ANY - * means values with any country code or no country code are - * removed. - */ - @Deprecated - public void clearDC(String element, String qualifier, String lang) - { - clearMetadata(MetadataSchema.DC_SCHEMA, element, qualifier, lang); - } - - /** - * Clear metadata values. As with getDC above, - * passing in null only matches fields where the qualifier or - * language is actually null.Item.ANY will - * match any element, qualifier or language, including null. - * Thus, item.clearDC(Item.ANY, Item.ANY, Item.ANY) will - * remove all Dublin Core metadata associated with an item. - * - * @param schema - * the schema for the metadata field. Must match - * the name of an existing metadata schema. - * @param element - * the Dublin Core element to remove, or Item.ANY - * @param qualifier - * the qualifier. null means unqualified, and - * Item.ANY means any qualifier (including - * unqualified.) - * @param lang - * the ISO639 language code, optionally followed by an underscore - * and the ISO3166 country code. null means only - * values with no language are removed, and Item.ANY - * means values with any country code or no country code are - * removed. - */ - public void clearMetadata(String schema, String element, String qualifier, - String lang) - { - // We will build a list of values NOT matching the values to clear - List values = new ArrayList(); - for (DCValue dcv : getMetadata()) - { - if (!match(schema, element, qualifier, lang, dcv)) - { - values.add(dcv); - } - } - - // Now swap the old list of values for the new, unremoved values - setMetadata(values); - dublinCoreChanged = true; - } - - /** - * Utility method for pattern-matching metadata elements. This - * method will return true if the given schema, - * element, qualifier and language match the schema, element, - * qualifier and language of the DCValue object passed - * in. Any or all of the element, qualifier and language passed - * in can be the Item.ANY wildcard. - * - * @param schema - * the schema for the metadata field. Must match - * the name of an existing metadata schema. - * @param element - * the element to match, or Item.ANY - * @param qualifier - * the qualifier to match, or Item.ANY - * @param language - * the language to match, or Item.ANY - * @param dcv - * the Dublin Core value - * @return true if there is a match - */ - private boolean match(String schema, String element, String qualifier, - String language, DCValue dcv) - { - // We will attempt to disprove a match - if we can't we have a match - if (!element.equals(Item.ANY) && !element.equals(dcv.element)) - { - // Elements do not match, no wildcard - return false; - } - - if (qualifier == null) - { - // Value must be unqualified - if (dcv.qualifier != null) - { - // Value is qualified, so no match - return false; - } - } - else if (!qualifier.equals(Item.ANY)) - { - // Not a wildcard, so qualifier must match exactly - if (!qualifier.equals(dcv.qualifier)) - { - return false; - } - } - - if (language == null) - { - // Value must be null language to match - if (dcv.language != null) - { - // Value is qualified, so no match - return false; - } - } - else if (!language.equals(Item.ANY)) - { - // Not a wildcard, so language must match exactly - if (!language.equals(dcv.language)) - { - return false; - } - } - - if (!schema.equals(Item.ANY)) - { - if (dcv.schema != null && !dcv.schema.equals(schema)) - { - // The namespace doesn't match - return false; - } - } - - // If we get this far, we have a match - return true; - } - /** * Get the e-person that originally submitted this item * @@ -1585,205 +995,7 @@ public void update() throws SQLException, AuthorizeException } } - // Map counting number of values for each element/qualifier. - // Keys are Strings: "element" or "element.qualifier" - // Values are Integers indicating number of values written for a - // element/qualifier - Map elementCount = new HashMap(); - - // Redo Dublin Core if it's changed - if (dublinCoreChanged) - { - dublinCoreChanged = false; - - // Arrays to store the working information required - int[] placeNum = new int[getMetadata().size()]; - boolean[] storedDC = new boolean[getMetadata().size()]; - MetadataField[] dcFields = new MetadataField[getMetadata().size()]; - - // Work out the place numbers for the in memory DC - for (int dcIdx = 0; dcIdx < getMetadata().size(); dcIdx++) - { - DCValue dcv = getMetadata().get(dcIdx); - - // Work out the place number for ordering - int current = 0; - - // Key into map is "element" or "element.qualifier" - String key = dcv.element + ((dcv.qualifier == null) ? "" : ("." + dcv.qualifier)); - - Integer currentInteger = elementCount.get(key); - if (currentInteger != null) - { - current = currentInteger.intValue(); - } - - current++; - elementCount.put(key, Integer.valueOf(current)); - - // Store the calculated place number, reset the stored flag, and cache the metadatafield - placeNum[dcIdx] = current; - storedDC[dcIdx] = false; - dcFields[dcIdx] = getMetadataField(dcv); - if (dcFields[dcIdx] == null) - { - // Bad DC field, log and throw exception - log.warn(LogManager - .getHeader(ourContext, "bad_dc", - "Bad DC field. schema="+dcv.schema - + ", element: \"" - + ((dcv.element == null) ? "null" - : dcv.element) - + "\" qualifier: \"" - + ((dcv.qualifier == null) ? "null" - : dcv.qualifier) - + "\" value: \"" - + ((dcv.value == null) ? "null" - : dcv.value) + "\"")); - - throw new SQLException("bad_dublin_core " - + "schema="+dcv.schema+", " - + dcv.element - + " " + dcv.qualifier); - } - } - - // Now the precalculations are done, iterate through the existing metadata - // looking for matches - TableRowIterator tri = retrieveMetadata(); - if (tri != null) - { - try - { - while (tri.hasNext()) - { - TableRow tr = tri.next(); - // Assume that we will remove this row, unless we get a match - boolean removeRow = true; - - // Go through the in-memory metadata, unless we've already decided to keep this row - for (int dcIdx = 0; dcIdx < getMetadata().size() && removeRow; dcIdx++) - { - // Only process if this metadata has not already been matched to something in the DB - if (!storedDC[dcIdx]) - { - boolean matched = true; - DCValue dcv = getMetadata().get(dcIdx); - - // Check the metadata field is the same - if (matched && dcFields[dcIdx].getFieldID() != tr.getIntColumn("metadata_field_id")) - { - matched = false; - } - - // Check the place is the same - if (matched && placeNum[dcIdx] != tr.getIntColumn("place")) - { - matched = false; - } - - // Check the text is the same - if (matched) - { - String text = tr.getStringColumn("text_value"); - if (dcv.value == null && text == null) - { - matched = true; - } - else if (dcv.value != null && dcv.value.equals(text)) - { - matched = true; - } - else - { - matched = false; - } - } - - // Check the language is the same - if (matched) - { - String lang = tr.getStringColumn("text_lang"); - if (dcv.language == null && lang == null) - { - matched = true; - } - else if (dcv.language != null && dcv.language.equals(lang)) - { - matched = true; - } - else - { - matched = false; - } - } - - // check that authority and confidence match - if (matched) - { - String auth = tr.getStringColumn("authority"); - int conf = tr.getIntColumn("confidence"); - if (!((dcv.authority == null && auth == null) || - (dcv.authority != null && auth != null && dcv.authority.equals(auth)) - && dcv.confidence == conf)) - { - matched = false; - } - } - - // If the db record is identical to the in memory values - if (matched) - { - // Flag that the metadata is already in the DB - storedDC[dcIdx] = true; - - // Flag that we are not going to remove the row - removeRow = false; - } - } - } - - // If after processing all the metadata values, we didn't find a match - // delete this row from the DB - if (removeRow) - { - DatabaseManager.delete(ourContext, tr); - dublinCoreChanged = true; - modified = true; - } - } - } - finally - { - tri.close(); - } - } - - // Add missing in-memory DC - for (int dcIdx = 0; dcIdx < getMetadata().size(); dcIdx++) - { - // Only write values that are not already in the db - if (!storedDC[dcIdx]) - { - DCValue dcv = getMetadata().get(dcIdx); - - // Write DCValue - MetadataValue metadata = new MetadataValue(); - metadata.setItemId(getID()); - metadata.setFieldId(dcFields[dcIdx].getFieldID()); - metadata.setValue(dcv.value); - metadata.setLanguage(dcv.language); - metadata.setPlace(placeNum[dcIdx]); - metadata.setAuthority(dcv.authority); - metadata.setConfidence(dcv.confidence); - metadata.create(ourContext); - dublinCoreChanged = true; - modified = true; - } - } - } - - if (dublinCoreChanged || modified) + if (modifiedMetadata || modified) { // Set the last modified date itemRow.setColumn("last_modified", new Date()); @@ -1807,12 +1019,9 @@ else if (dcv.language != null && dcv.language.equals(lang)) DatabaseManager.update(ourContext, itemRow); - if (dublinCoreChanged) - { - ourContext.addEvent(new Event(Event.MODIFY_METADATA, Constants.ITEM, getID(), - getDetails(), getIdentifiers(ourContext))); + if (modifiedMetadata) { + updateMetadata(); clearDetails(); - dublinCoreChanged = false; } ourContext.addEvent(new Event(Event.MODIFY, Constants.ITEM, getID(), @@ -1821,45 +1030,6 @@ else if (dcv.language != null && dcv.language.equals(lang)) } } - private transient MetadataField[] allMetadataFields = null; - private MetadataField getMetadataField(DCValue dcv) throws SQLException, AuthorizeException - { - if (allMetadataFields == null) - { - allMetadataFields = MetadataField.findAll(ourContext); - } - - if (allMetadataFields != null) - { - int schemaID = getMetadataSchemaID(dcv); - for (MetadataField field : allMetadataFields) - { - if (field.getSchemaID() == schemaID && - StringUtils.equals(field.getElement(), dcv.element) && - StringUtils.equals(field.getQualifier(), dcv.qualifier)) - { - return field; - } - } - } - - return null; - } - - private int getMetadataSchemaID(DCValue dcv) throws SQLException - { - int schemaID; - MetadataSchema schema = MetadataSchema.find(ourContext,dcv.schema); - if (schema == null) - { - schemaID = MetadataSchema.DC_SCHEMA_ID; - } - else - { - schemaID = schema.getSchemaID(); - } - return schemaID; - } /** * Withdraw the item from the archive. It is kept in place, and the content @@ -1919,6 +1089,7 @@ public void withdraw() throws SQLException, AuthorizeException, IOException + e.getEmail() + ",item_id=" + getID())); } + /** * Reinstate a withdrawn item * @@ -2169,19 +1340,6 @@ public boolean isOwningCollection(Collection c) return false; } - /** - * Utility method to remove all descriptive metadata associated with the item from - * the database (regardless of in-memory version) - * - * @throws SQLException - */ - private void removeMetadataFromDatabase() throws SQLException - { - DatabaseManager.updateQuery(ourContext, - "DELETE FROM MetadataValue WHERE item_id= ? ", - getID()); - } - /** * return type found in Constants * @@ -2529,10 +1687,9 @@ public boolean canEdit() throws java.sql.SQLException public String getName() { - DCValue t[] = getMetadata("dc", "title", null, Item.ANY); - return (t.length >= 1) ? t[0].value : null; + return getMetadataFirstValue(MetadataSchema.DC_SCHEMA, "title", null, Item.ANY); } - + /** * Returns an iterator of Items possessing the passed metadata field, or only * those matching the passed value, if value is not Item.ANY @@ -2563,16 +1720,16 @@ public static ItemIterator findByMetadataField(Context context, } String query = "SELECT item.* FROM metadatavalue,item WHERE item.in_archive='1' "+ - "AND item.item_id = metadatavalue.item_id AND metadata_field_id = ?"; + "AND item.item_id = metadatavalue.resource_id AND metadata_field_id = ? AND resource_type_id = ?"; TableRowIterator rows = null; if (Item.ANY.equals(value)) { - rows = DatabaseManager.queryTable(context, "item", query, mdf.getFieldID()); + rows = DatabaseManager.queryTable(context, "item", query, mdf.getFieldID(), Constants.ITEM); } else { query += " AND metadatavalue.text_value = ?"; - rows = DatabaseManager.queryTable(context, "item", query, mdf.getFieldID(), value); + rows = DatabaseManager.queryTable(context, "item", query, mdf.getFieldID(), Constants.ITEM, value); } return new ItemIterator(context, rows); } @@ -2741,116 +1898,15 @@ public static ItemIterator findByAuthorityValue(Context context, TableRowIterator rows = DatabaseManager.queryTable(context, "item", "SELECT item.* FROM metadatavalue,item WHERE item.in_archive='1' "+ - "AND item.item_id = metadatavalue.item_id AND metadata_field_id = ? AND authority = ?", - mdf.getFieldID(), value); + "AND item.item_id = metadatavalue.resource_id AND metadata_field_id = ? AND authority = ? AND resource_type_id = ?", + mdf.getFieldID(), value, Constants.ITEM); return new ItemIterator(context, rows); } - - private List getMetadata() - { - try - { - return dublinCore.get(ourContext, getID(), log); - } - catch (SQLException e) - { - log.error("Loading item - cannot load metadata"); - } - - return new ArrayList(); - } - - private void setMetadata(List metadata) - { - dublinCore.set(metadata); - dublinCoreChanged = true; - } - - class MetadataCache - { - List metadata = null; - - List get(Context c, int itemId, Logger log) throws SQLException - { - if (metadata == null) - { - metadata = new ArrayList(); - - // Get Dublin Core metadata - TableRowIterator tri = retrieveMetadata(itemId); - - if (tri != null) - { - try - { - while (tri.hasNext()) - { - TableRow resultRow = tri.next(); - - // Get the associated metadata field and schema information - int fieldID = resultRow.getIntColumn("metadata_field_id"); - MetadataField field = MetadataField.find(c, fieldID); - - if (field == null) - { - log.error("Loading item - cannot find metadata field " + fieldID); - } - else - { - MetadataSchema schema = MetadataSchema.find(c, field.getSchemaID()); - if (schema == null) - { - log.error("Loading item - cannot find metadata schema " + field.getSchemaID() + ", field " + fieldID); - } - else - { - // Make a DCValue object - DCValue dcv = new DCValue(); - dcv.element = field.getElement(); - dcv.qualifier = field.getQualifier(); - dcv.value = resultRow.getStringColumn("text_value"); - dcv.language = resultRow.getStringColumn("text_lang"); - //dcv.namespace = schema.getNamespace(); - dcv.schema = schema.getName(); - dcv.authority = resultRow.getStringColumn("authority"); - dcv.confidence = resultRow.getIntColumn("confidence"); - - // Add it to the list - metadata.add(dcv); - } - } - } - } - finally - { - // close the TableRowIterator to free up resources - if (tri != null) - { - tri.close(); - } - } - } - } - - return metadata; - } - - void set(List m) - { - metadata = m; - } - - TableRowIterator retrieveMetadata(int itemId) throws SQLException - { - if (itemId > 0) - { - return DatabaseManager.queryTable(ourContext, "MetadataValue", - "SELECT * FROM MetadataValue WHERE item_id= ? ORDER BY metadata_field_id, place", - itemId); - } - - return null; - } + @Override + protected void getAuthoritiesAndConfidences(String fieldKey, String[] values, String[] authorities, int[] confidences, int i) { + Choices c = ChoiceAuthorityManager.getManager().getBestMatch(fieldKey, values[i], getOwningCollectionID(), null); + authorities[i] = c.values.length > 0 ? c.values[0].authority : null; + confidences[i] = c.confidence; } } diff --git a/dspace-api/src/main/java/org/dspace/content/MetadataField.java b/dspace-api/src/main/java/org/dspace/content/MetadataField.java index d904f70e6147..3c74c09c8dd6 100644 --- a/dspace-api/src/main/java/org/dspace/content/MetadataField.java +++ b/dspace-api/src/main/java/org/dspace/content/MetadataField.java @@ -53,6 +53,9 @@ public class MetadataField // cache of field by ID (Integer) private static Map id2field = null; + /** metadatafield cache */ + private static Map metadatafieldcache = null; + /** * Default constructor. @@ -270,51 +273,20 @@ public void create(Context context) throws IOException, AuthorizeException, * @throws AuthorizeException */ public static MetadataField findByElement(Context context, int schemaID, - String element, String qualifier) throws SQLException, - AuthorizeException + String element, String qualifier) throws SQLException { - // Grab rows from DB - TableRowIterator tri; - if (qualifier == null) - { - tri = DatabaseManager.queryTable(context,"MetadataFieldRegistry", - "SELECT * FROM MetadataFieldRegistry WHERE metadata_schema_id= ? " + - "AND element= ? AND qualifier is NULL ", - schemaID, element); - } - else - { - tri = DatabaseManager.queryTable(context,"MetadataFieldRegistry", - "SELECT * FROM MetadataFieldRegistry WHERE metadata_schema_id= ? " + - "AND element= ? AND qualifier= ? ", - schemaID, element, qualifier); - } - - TableRow row = null; - try - { - if (tri.hasNext()) - { - row = tri.next(); - } - } - finally - { - // close the TableRowIterator to free up resources - if (tri != null) - { - tri.close(); - } + + if (!isCacheInitialized()){ + initCache(context); } - if (row == null) - { + // 'sanity check' first. + String metadataFieldKey = schemaID+"."+element+"."+qualifier; + if(!metadatafieldcache.containsKey(metadataFieldKey)) { return null; } - else - { - return new MetadataField(row); - } + + return metadatafieldcache.get(metadataFieldKey); } /** @@ -629,6 +601,7 @@ private static synchronized void initCache(Context context) throws SQLException if (!isCacheInitialized()) { Map new_id2field = new HashMap(); + Map new_metadatafieldcache = new HashMap(); log.info("Loading MetadataField elements into cache."); // Grab rows from DB @@ -641,7 +614,9 @@ private static synchronized void initCache(Context context) throws SQLException { TableRow row = tri.next(); int fieldID = row.getIntColumn("metadata_field_id"); - new_id2field.put(Integer.valueOf(fieldID), new MetadataField(row)); + MetadataField metadataField = new MetadataField(row); + new_id2field.put(Integer.valueOf(fieldID), metadataField); + new_metadatafieldcache.put(metadataField.getSchemaID()+"."+metadataField.getElement()+"."+metadataField.getQualifier(), metadataField); } } finally @@ -654,6 +629,7 @@ private static synchronized void initCache(Context context) throws SQLException } id2field = new_id2field; + metadatafieldcache = new_metadatafieldcache; } } diff --git a/dspace-api/src/main/java/org/dspace/content/MetadataValue.java b/dspace-api/src/main/java/org/dspace/content/MetadataValue.java index 1e191c6fb1a2..608ec7fa2001 100644 --- a/dspace-api/src/main/java/org/dspace/content/MetadataValue.java +++ b/dspace-api/src/main/java/org/dspace/content/MetadataValue.java @@ -38,8 +38,11 @@ public class MetadataValue /** The primary key for the metadata value */ private int valueId = 0; - /** The reference to the DSpace item */ - private int itemId; + /** The reference to the DSpace resource */ + private int resourceId; + + /** The reference to the DSpace resource type*/ + private int resourceTypeId; /** The value of the field */ public String value; @@ -73,7 +76,8 @@ public MetadataValue(TableRow row) { fieldId = row.getIntColumn("metadata_field_id"); valueId = row.getIntColumn("metadata_value_id"); - itemId = row.getIntColumn("item_id"); + resourceId = row.getIntColumn("resource_id"); + resourceTypeId = row.getIntColumn("resource_type_id"); value = row.getStringColumn("text_value"); language = row.getStringColumn("text_lang"); place = row.getIntColumn("place"); @@ -121,23 +125,39 @@ public void setFieldId(int fieldId) } /** - * Get the item ID. + * Get the resource type ID. * - * @return item ID + * @return resource type ID */ - public int getItemId() - { - return itemId; + public int getResourceTypeId() { + return resourceTypeId; } /** - * Set the item ID. + * Set the resource type ID. * - * @param itemId new item ID + * @param resourceTypeId new resource type ID */ - public void setItemId(int itemId) - { - this.itemId = itemId; + public void setResourceTypeId(int resourceTypeId) { + this.resourceTypeId = resourceTypeId; + } + + /** + * Get the resource id + * + * @return resource ID + */ + public int getResourceId() { + return resourceId; + } + + /** + * Set the resource type ID. + * + * @param resourceId new resource ID + */ + public void setResourceId(int resourceId) { + this.resourceId = resourceId; } /** @@ -262,7 +282,8 @@ public void create(Context context) throws SQLException, AuthorizeException { // Create a table row and update it with the values row = DatabaseManager.row("MetadataValue"); - row.setColumn("item_id", itemId); + row.setColumn("resource_id", resourceId); + row.setColumn("resource_type_id", resourceTypeId); row.setColumn("metadata_field_id", fieldId); row.setColumn("text_value", value); row.setColumn("text_lang", language); @@ -372,7 +393,8 @@ public static List findByField(Context context, int fieldId) */ public void update(Context context) throws SQLException, AuthorizeException { - row.setColumn("item_id", itemId); + row.setColumn("resource_id", resourceId); + row.setColumn("resource_type_id", resourceTypeId); row.setColumn("metadata_field_id", fieldId); row.setColumn("text_value", value); row.setColumn("text_lang", language); @@ -429,7 +451,11 @@ public boolean equals(Object obj) { return false; } - if (this.itemId != other.itemId) + if (this.resourceId != other.resourceId) + { + return false; + } + if (this.resourceTypeId != other.resourceTypeId) { return false; } @@ -442,7 +468,8 @@ public int hashCode() int hash = 7; hash = 47 * hash + this.fieldId; hash = 47 * hash + this.valueId; - hash = 47 * hash + this.itemId; + hash = 47 * hash + this.resourceId; + hash = 47 * hash + this.resourceTypeId; return hash; } } diff --git a/dspace-api/src/main/java/org/dspace/content/SupervisedItem.java b/dspace-api/src/main/java/org/dspace/content/SupervisedItem.java index 37319cb54355..cc17e31cb3af 100644 --- a/dspace-api/src/main/java/org/dspace/content/SupervisedItem.java +++ b/dspace-api/src/main/java/org/dspace/content/SupervisedItem.java @@ -105,8 +105,7 @@ public Group[] getSupervisorGroups(Context c, int wi) "WHERE epersongroup2workspaceitem.workspace_item_id" + " = ? " + " AND epersongroup2workspaceitem.eperson_group_id =" + - " epersongroup.eperson_group_id " + - "ORDER BY epersongroup.name"; + " epersongroup.eperson_group_id "; TableRowIterator tri = DatabaseManager.queryTable(c,"epersongroup",query, wi); @@ -151,8 +150,7 @@ public Group[] getSupervisorGroups() "WHERE epersongroup2workspaceitem.workspace_item_id" + " = ? " + " AND epersongroup2workspaceitem.eperson_group_id =" + - " epersongroup.eperson_group_id " + - "ORDER BY epersongroup.name"; + " epersongroup.eperson_group_id "; TableRowIterator tri = DatabaseManager.queryTable(ourContext, "epersongroup", diff --git a/dspace-api/src/main/java/org/dspace/content/service/ItemService.java b/dspace-api/src/main/java/org/dspace/content/service/ItemService.java index 47c70f912f82..11943a664194 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/ItemService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/ItemService.java @@ -53,7 +53,7 @@ public static Thumbnail getThumbnail(Context context, int itemId, boolean requir } public static String getFirstMetadataValue(Item item, String metadataKey) { - DCValue[] dcValue = item.getMetadata(metadataKey); + DCValue[] dcValue = item.getMetadataByMetadataString(metadataKey); if(dcValue.length > 0) { return dcValue[0].value; } else { diff --git a/dspace-api/src/main/java/org/dspace/ctask/general/AbstractTranslator.java b/dspace-api/src/main/java/org/dspace/ctask/general/AbstractTranslator.java index 1068c64d791f..98ae0a447a69 100644 --- a/dspace-api/src/main/java/org/dspace/ctask/general/AbstractTranslator.java +++ b/dspace-api/src/main/java/org/dspace/ctask/general/AbstractTranslator.java @@ -89,7 +89,7 @@ public int perform(DSpaceObject dso) throws IOException String handle = item.getHandle(); log.debug("Translating metadata for " + handle); - DCValue[] authLangs = item.getMetadata(authLangField); + DCValue[] authLangs = item.getMetadataByMetadataString(authLangField); if(authLangs.length > 0) { /* Assume the first... multiple diff --git a/dspace-api/src/main/java/org/dspace/ctask/general/MetadataWebService.java b/dspace-api/src/main/java/org/dspace/ctask/general/MetadataWebService.java index e58e83f0c4c3..325ac77d034f 100644 --- a/dspace-api/src/main/java/org/dspace/ctask/general/MetadataWebService.java +++ b/dspace-api/src/main/java/org/dspace/ctask/general/MetadataWebService.java @@ -236,7 +236,7 @@ public int perform(DSpaceObject dso) throws IOException { } resultSb.append(itemId); // Only proceed if item has a value for service template parameter - DCValue[] dcVals = item.getMetadata(lookupField); + DCValue[] dcVals = item.getMetadataByMetadataString(lookupField); if (dcVals.length > 0 && dcVals[0].value.length() > 0) { String value = transform(dcVals[0].value, lookupTransform); status = callService(value, item, resultSb); diff --git a/dspace-api/src/main/java/org/dspace/ctask/general/RequiredMetadata.java b/dspace-api/src/main/java/org/dspace/ctask/general/RequiredMetadata.java index 0ebf3d4c8e70..cbddf21c86fb 100644 --- a/dspace-api/src/main/java/org/dspace/ctask/general/RequiredMetadata.java +++ b/dspace-api/src/main/java/org/dspace/ctask/general/RequiredMetadata.java @@ -81,7 +81,7 @@ public int perform(DSpaceObject dso) throws IOException sb.append("Item: ").append(handle); for (String req : getReqList(item.getOwningCollection().getHandle())) { - DCValue[] vals = item.getMetadata(req); + DCValue[] vals = item.getMetadataByMetadataString(req); if (vals.length == 0) { sb.append(" missing required field: ").append(req); diff --git a/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java b/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java index 0a1176c4bac6..ebecacbf3387 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java @@ -1320,7 +1320,7 @@ protected void buildDocument(Context context, Item item) try { - DCValue[] values = item.getMetadata("dc.relation.ispartof"); + DCValue[] values = item.getMetadataByMetadataString("dc.relation.ispartof"); if(values != null && values.length > 0 && values[0] != null && values[0].value != null) { diff --git a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java index b88e0cc1ef5d..5116569bac05 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/EPerson.java +++ b/dspace-api/src/main/java/org/dspace/eperson/EPerson.java @@ -24,7 +24,7 @@ import org.apache.log4j.Logger; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeManager; -import org.dspace.content.DSpaceObject; +import org.dspace.content.*; import org.dspace.core.ConfigurationManager; import org.dspace.core.Constants; import org.dspace.core.Context; @@ -61,18 +61,12 @@ public class EPerson extends DSpaceObject /** log4j logger */ private static final Logger log = Logger.getLogger(EPerson.class); - /** Our context */ - private final Context myContext; - /** The row in the table representing this eperson */ private final TableRow myRow; /** Flag set when data is modified, for events */ private boolean modified; - /** Flag set when metadata is modified, for events */ - private boolean modifiedMetadata; - /** * Construct an EPerson * @@ -81,15 +75,13 @@ public class EPerson extends DSpaceObject * @param row * the corresponding row in the table */ - EPerson(Context context, TableRow row) - { - myContext = context; + EPerson(Context context, TableRow row) throws SQLException { + super(context); myRow = row; // Cache ourselves context.cache(this, row.getIntColumn("eperson_id")); modified = false; - modifiedMetadata = false; clearDetails(); } @@ -290,8 +282,17 @@ public static EPerson[] search(Context context, String query, int offset, int li { String params = "%"+query.toLowerCase()+"%"; StringBuffer queryBuf = new StringBuffer(); - queryBuf.append("SELECT * FROM eperson WHERE eperson_id = ? OR "); - queryBuf.append("LOWER(firstname) LIKE LOWER(?) OR LOWER(lastname) LIKE LOWER(?) OR LOWER(email) LIKE LOWER(?) ORDER BY lastname, firstname ASC "); + queryBuf.append("select e.* from eperson e " + + " LEFT JOIN metadatavalue fn on (resource_id=e.eperson_id AND fn.resource_type_id=? and fn.metadata_field_id=?) " + + " LEFT JOIN metadatavalue ln on (ln.resource_id=e.eperson_id AND ln.resource_type_id=? and ln.metadata_field_id=?) " + + " WHERE e.eperson_id = ? OR " + + "LOWER(fn.text_value) LIKE LOWER(?) OR LOWER(ln.text_value) LIKE LOWER(?) OR LOWER(email) LIKE LOWER(?) ORDER BY "); + + if(DatabaseManager.isOracle()) { + queryBuf.append(" dbms_lob.substr(ln.text_value), dbms_lob.substr(fn.text_value) ASC"); + }else{ + queryBuf.append(" ln.text_value, fn.text_value ASC"); + } // Add offset and limit restrictions - Oracle requires special code if (DatabaseManager.isOracle()) @@ -341,23 +342,28 @@ public static EPerson[] search(Context context, String query, int offset, int li try { int_param = Integer.valueOf(query); } + catch (NumberFormatException e) { int_param = Integer.valueOf(-1); } + + Integer f = MetadataField.findByElement(context, MetadataSchema.find(context, "eperson").getSchemaID(), "firstname", null).getFieldID(); + Integer l = MetadataField.findByElement(context, MetadataSchema.find(context, "eperson").getSchemaID(), "lastname", null).getFieldID(); + // Create the parameter array, including limit and offset if part of the query - Object[] paramArr = new Object[] {int_param,params,params,params}; + Object[] paramArr = new Object[] {Constants.EPERSON,f, Constants.EPERSON,l, int_param,params,params,params}; if (limit > 0 && offset > 0) { - paramArr = new Object[]{int_param, params, params, params, limit, offset}; + paramArr = new Object[]{Constants.EPERSON,f, Constants.EPERSON,l, int_param,params,params,params, limit, offset}; } else if (limit > 0) { - paramArr = new Object[]{int_param, params, params, params, limit}; + paramArr = new Object[]{Constants.EPERSON,f, Constants.EPERSON,l, int_param,params,params,params, limit}; } else if (offset > 0) { - paramArr = new Object[]{int_param, params, params, params, offset}; + paramArr = new Object[]{Constants.EPERSON,f, Constants.EPERSON,l, int_param,params,params,params, offset}; } // Get all the epeople that match the query @@ -422,12 +428,29 @@ public static int searchResultCount(Context context, String query) catch (NumberFormatException e) { int_param = Integer.valueOf(-1); } - + // Get all the epeople that match the query TableRow row = DatabaseManager.querySingle(context, - "SELECT count(*) as epcount FROM eperson WHERE eperson_id = ? OR " + - "LOWER(firstname) LIKE LOWER(?) OR LOWER(lastname) LIKE LOWER(?) OR LOWER(email) LIKE LOWER(?)", - new Object[] {int_param,dbquery,dbquery,dbquery}); + "SELECT count(*) as epcount FROM eperson " + + "WHERE eperson_id = ? OR " + + "LOWER((select text_value from metadatavalue where resource_id=? and resource_type_id=? and metadata_field_id=?)) LIKE LOWER(?) " + + "OR LOWER((select text_value from metadatavalue where resource_id=? and resource_type_id=? and metadata_field_id=?)) LIKE LOWER(?) " + + "OR LOWER(eperson.email) LIKE LOWER(?)", + new Object[] { + int_param, + + int_param, + Constants.EPERSON, + MetadataField.findByElement(context, MetadataSchema.find(context, "eperson").getSchemaID(), "firstname", null).getFieldID(), + dbquery, + + int_param, + Constants.EPERSON, + MetadataField.findByElement(context, MetadataSchema.find(context, "eperson").getSchemaID(), "lastname", null).getFieldID(), + dbquery, + + dbquery + }); // use getIntColumn for Oracle count data if (DatabaseManager.isOracle()) @@ -458,33 +481,47 @@ public static int searchResultCount(Context context, String query) public static EPerson[] findAll(Context context, int sortField) throws SQLException { - String s; + String s, t = "", theQuery = ""; switch (sortField) { case ID: - s = "eperson_id"; + s = "e.eperson_id"; break; case EMAIL: - s = "email"; + s = "e.email"; break; case LANGUAGE: - s = "language"; + s = "m_text_value"; + t = "language"; break; case NETID: - s = "netid"; + s = "m_text_value"; + t = "netid"; break; default: - s = "lastname"; + s = "m_text_value"; + t = "lastname"; } - // NOTE: The use of 's' in the order by clause can not cause an SQL + // NOTE: The use of 's' in the order by clause can not cause an SQL // injection because the string is derived from constant values above. - TableRowIterator rows = DatabaseManager.query(context, - "SELECT * FROM eperson ORDER BY "+s); + TableRowIterator rows = DatabaseManager.query(context, "SELECT * FROM eperson e ORDER BY ?",s); + if(t!="") { + rows = DatabaseManager.query(context, + "SELECT * FROM eperson e " + + "LEFT JOIN metadatavalue m on (m.resource_id = e.eperson_id and m.resource_type_id = ? and m.metadata_field_id = ?) " + + "ORDER BY ?", + Constants.EPERSON, + MetadataField.findByElement(context, MetadataSchema.find(context, "eperson").getSchemaID(), t, null).getFieldID(), + s + ); + } + + try { @@ -559,7 +596,7 @@ public void delete() throws SQLException, AuthorizeException, EPersonDeletionException { // authorized? - if (!AuthorizeManager.isAdmin(myContext)) + if (!AuthorizeManager.isAdmin(ourContext)) { throw new AuthorizeException( "You must be an admin to delete an EPerson"); @@ -576,29 +613,31 @@ public void delete() throws SQLException, AuthorizeException, throw new EPersonDeletionException(constraintList); } - myContext.addEvent(new Event(Event.DELETE, Constants.EPERSON, getID(), - getEmail(), getIdentifiers(myContext))); + // Delete the Dublin Core + removeMetadataFromDatabase(); + + ourContext.addEvent(new Event(Event.DELETE, Constants.EPERSON, getID(), getEmail(), getIdentifiers(ourContext))); // Remove from cache - myContext.removeCached(this, getID()); + ourContext.removeCached(this, getID()); // XXX FIXME: This sidesteps the object model code so it won't // generate REMOVE events on the affected Groups. // Remove any group memberships first - DatabaseManager.updateQuery(myContext, + DatabaseManager.updateQuery(ourContext, "DELETE FROM EPersonGroup2EPerson WHERE eperson_id= ? ", getID()); // Remove any subscriptions - DatabaseManager.updateQuery(myContext, + DatabaseManager.updateQuery(ourContext, "DELETE FROM subscription WHERE eperson_id= ? ", getID()); // Remove ourself - DatabaseManager.delete(myContext, myRow); + DatabaseManager.delete(ourContext, myRow); - log.info(LogManager.getHeader(myContext, "delete_eperson", + log.info(LogManager.getHeader(ourContext, "delete_eperson", "eperson_id=" + getID())); } @@ -619,7 +658,7 @@ public int getID() */ public String getLanguage() { - return myRow.getStringColumn("language"); + return getMetadataFirstValue("eperson", "language", null, Item.ANY); } /** @@ -630,9 +669,8 @@ public String getLanguage() * @param language * language code */ - public void setLanguage(String language) - { - myRow.setColumn("language", language); + public void setLanguage(String language) { + setMetadataSingleValue("eperson", "language", null, null, language); } @@ -681,7 +719,7 @@ public void setEmail(String s) */ public String getNetid() { - return myRow.getStringColumn("netid"); + return getMetadataFirstValue("eperson", "netid", null, Item.ANY); } /** @@ -690,9 +728,8 @@ public String getNetid() * @param s * the new netid */ - public void setNetid(String s) - { - myRow.setColumn("netid", s); + public void setNetid(String s) { + setMetadataSingleValue("eperson", "netid", null, null, s); modified = true; } @@ -704,8 +741,8 @@ public void setNetid(String s) */ public String getFullName() { - String f = myRow.getStringColumn("firstname"); - String l = myRow.getStringColumn("lastname"); + String f = getFirstName(); + String l= getLastName(); if ((l == null) && (f == null)) { @@ -728,7 +765,7 @@ else if (f == null) */ public String getFirstName() { - return myRow.getStringColumn("firstname"); + return getMetadataFirstValue("eperson", "firstname", null, Item.ANY); } /** @@ -737,9 +774,8 @@ public String getFirstName() * @param firstname * the person's first name */ - public void setFirstName(String firstname) - { - myRow.setColumn("firstname", firstname); + public void setFirstName(String firstname) { + setMetadataSingleValue("eperson", "firstname", null, null, firstname); modified = true; } @@ -750,7 +786,7 @@ public void setFirstName(String firstname) */ public String getLastName() { - return myRow.getStringColumn("lastname"); + return getMetadataFirstValue("eperson", "lastname", null, Item.ANY); } /** @@ -759,9 +795,8 @@ public String getLastName() * @param lastname * the person's last name */ - public void setLastName(String lastname) - { - myRow.setColumn("lastname", lastname); + public void setLastName(String lastname) { + setMetadataSingleValue("eperson", "lastname", null, null, lastname); modified = true; } @@ -833,18 +868,20 @@ public boolean getSelfRegistered() /** * Get the value of a metadata field - * + * * @param field * the name of the metadata field to get - * + * * @return the value of the metadata field (or null if the column is an SQL NULL) - * + * * @exception IllegalArgumentException * if the requested metadata field doesn't exist */ + @Deprecated public String getMetadata(String field) { - return myRow.getStringColumn(field); + String[] MDValue = getMDValueByLegacyField(field); + return getMetadataFirstValue(MDValue[0], MDValue[1], MDValue[2], Item.ANY); } /** @@ -858,11 +895,11 @@ public String getMetadata(String field) * @exception IllegalArgumentException * if the requested metadata field doesn't exist */ + @Deprecated public void setMetadata(String field, String value) { - myRow.setColumn(field, value); - modifiedMetadata = true; - addDetails(field); + String[] MDValue = getMDValueByLegacyField(field); + setMetadataSingleValue(MDValue[0], MDValue[1], MDValue[2], null, value); } /** @@ -951,14 +988,14 @@ public boolean checkPassword(String attempt) log.info("Upgrading password hash for EPerson " + getID()); setPassword(attempt); try { - myContext.turnOffAuthorisationSystem(); + ourContext.turnOffAuthorisationSystem(); update(); } catch (SQLException ex) { log.error("Could not update password hash", ex); } catch (AuthorizeException ex) { log.error("Could not update password hash", ex); } finally { - myContext.restoreAuthSystemState(); + ourContext.restoreAuthSystemState(); } } @@ -992,29 +1029,27 @@ public void update() throws SQLException, AuthorizeException { // Check authorisation - if you're not the eperson // see if the authorization system says you can - if (!myContext.ignoreAuthorization() - && ((myContext.getCurrentUser() == null) || (getID() != myContext + if (!ourContext.ignoreAuthorization() + && ((ourContext.getCurrentUser() == null) || (getID() != ourContext .getCurrentUser().getID()))) { - AuthorizeManager.authorizeAction(myContext, this, Constants.WRITE); + AuthorizeManager.authorizeAction(ourContext, this, Constants.WRITE); } - DatabaseManager.update(myContext, myRow); + DatabaseManager.update(ourContext, myRow); - log.info(LogManager.getHeader(myContext, "update_eperson", + log.info(LogManager.getHeader(ourContext, "update_eperson", "eperson_id=" + getID())); if (modified) { - myContext.addEvent(new Event(Event.MODIFY, Constants.EPERSON, - getID(), null, getIdentifiers(myContext))); + ourContext.addEvent(new Event(Event.MODIFY, Constants.EPERSON, + getID(), null, getIdentifiers(ourContext))); modified = false; } if (modifiedMetadata) { - myContext.addEvent(new Event(Event.MODIFY_METADATA, Constants.EPERSON, - getID(), getDetails(), getIdentifiers(myContext))); - modifiedMetadata = false; + updateMetadata(); clearDetails(); } } @@ -1042,7 +1077,7 @@ public List getDeleteConstraints() throws SQLException List tableList = new ArrayList(); // check for eperson in item table - TableRowIterator tri = DatabaseManager.query(myContext, + TableRowIterator tri = DatabaseManager.query(ourContext, "SELECT * from item where submitter_id= ? ", getID()); @@ -1076,7 +1111,7 @@ public List getDeleteConstraints() throws SQLException private void getXMLWorkflowConstraints(List tableList) throws SQLException { TableRowIterator tri; // check for eperson in claimtask table - tri = DatabaseManager.queryTable(myContext, "cwf_claimtask", + tri = DatabaseManager.queryTable(ourContext, "cwf_claimtask", "SELECT * from cwf_claimtask where owner_id= ? ", getID()); @@ -1097,7 +1132,7 @@ private void getXMLWorkflowConstraints(List tableList) throws SQLExcepti } // check for eperson in pooltask table - tri = DatabaseManager.queryTable(myContext, "cwf_pooltask", + tri = DatabaseManager.queryTable(ourContext, "cwf_pooltask", "SELECT * from cwf_pooltask where eperson_id= ? ", getID()); @@ -1118,7 +1153,7 @@ private void getXMLWorkflowConstraints(List tableList) throws SQLExcepti } // check for eperson in workflowitemrole table - tri = DatabaseManager.queryTable(myContext, "cwf_workflowitemrole", + tri = DatabaseManager.queryTable(ourContext, "cwf_workflowitemrole", "SELECT * from cwf_workflowitemrole where eperson_id= ? ", getID()); @@ -1143,7 +1178,7 @@ private void getXMLWorkflowConstraints(List tableList) throws SQLExcepti private void getOriginalWorkflowConstraints(List tableList) throws SQLException { TableRowIterator tri; // check for eperson in workflowitem table - tri = DatabaseManager.query(myContext, + tri = DatabaseManager.query(ourContext, "SELECT * from workflowitem where owner= ? ", getID()); @@ -1164,7 +1199,7 @@ private void getOriginalWorkflowConstraints(List tableList) throws SQLEx } // check for eperson in tasklistitem table - tri = DatabaseManager.query(myContext, + tri = DatabaseManager.query(ourContext, "SELECT * from tasklistitem where eperson_id= ? ", getID()); @@ -1223,8 +1258,7 @@ public void updateLastModified() * Tool for manipulating user accounts. */ public static void main(String argv[]) - throws ParseException, SQLException - { + throws ParseException, SQLException, AuthorizeException { final OptionGroup VERBS = new OptionGroup(); VERBS.addOption(VERB_ADD); VERBS.addOption(VERB_DELETE); @@ -1284,8 +1318,7 @@ else if (command.hasOption('h')) } /** Command to create an EPerson. */ - private static int cmdAdd(Context context, String[] argv) - { + private static int cmdAdd(Context context, String[] argv) throws AuthorizeException { Options options = new Options(); options.addOption(VERB_ADD); @@ -1455,8 +1488,7 @@ else if (command.hasOption(OPT_EMAIL.getOpt())) } /** Command to modify an EPerson. */ - private static int cmdModify(Context context, String[] argv) - { + private static int cmdModify(Context context, String[] argv) throws AuthorizeException { Options options = new Options(); options.addOption(VERB_MODIFY); diff --git a/dspace-api/src/main/java/org/dspace/eperson/Group.java b/dspace-api/src/main/java/org/dspace/eperson/Group.java index 8cb3a9fc7a10..8f3dca29b087 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/Group.java +++ b/dspace-api/src/main/java/org/dspace/eperson/Group.java @@ -20,9 +20,7 @@ import org.dspace.authorize.AuthorizeConfiguration; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeManager; -import org.dspace.content.Collection; -import org.dspace.content.Community; -import org.dspace.content.DSpaceObject; +import org.dspace.content.*; import org.dspace.core.ConfigurationManager; import org.dspace.core.Constants; import org.dspace.core.Context; @@ -54,9 +52,6 @@ public class Group extends DSpaceObject /** ID of Administrator Group */ public static final int ADMIN_ID = 1; - /** Our context */ - private final Context myContext; - /** The row in the table representing this object */ private final TableRow myRow; @@ -73,8 +68,6 @@ public class Group extends DSpaceObject /** is this just a stub, or is all data loaded? */ private boolean isDataLoaded = false; - /** Flag set when metadata is modified, for events */ - private boolean modifiedMetadata; /** * Construct a Group from a given context and tablerow @@ -84,13 +77,12 @@ public class Group extends DSpaceObject */ Group(Context context, TableRow row) throws SQLException { - myContext = context; + super(context); myRow = row; // Cache ourselves context.cache(this, row.getIntColumn("eperson_group_id")); - modifiedMetadata = false; clearDetails(); } @@ -110,7 +102,7 @@ public void loadData() try { // get epeople objects - TableRowIterator tri = DatabaseManager.queryTable(myContext,"eperson", + TableRowIterator tri = DatabaseManager.queryTable(ourContext,"eperson", "SELECT eperson.* FROM eperson, epersongroup2eperson WHERE " + "epersongroup2eperson.eperson_id=eperson.eperson_id AND " + "epersongroup2eperson.eperson_group_id= ?", @@ -123,7 +115,7 @@ public void loadData() TableRow r = (TableRow) tri.next(); // First check the cache - EPerson fromCache = (EPerson) myContext.fromCache( + EPerson fromCache = (EPerson) ourContext.fromCache( EPerson.class, r.getIntColumn("eperson_id")); if (fromCache != null) @@ -132,7 +124,7 @@ public void loadData() } else { - epeople.add(new EPerson(myContext, r)); + epeople.add(new EPerson(ourContext, r)); } } } @@ -146,7 +138,7 @@ public void loadData() } // now get Group objects - tri = DatabaseManager.queryTable(myContext,"epersongroup", + tri = DatabaseManager.queryTable(ourContext,"epersongroup", "SELECT epersongroup.* FROM epersongroup, group2group WHERE " + "group2group.child_id=epersongroup.eperson_group_id AND "+ "group2group.parent_id= ? ", @@ -159,7 +151,7 @@ public void loadData() TableRow r = (TableRow) tri.next(); // First check the cache - Group fromCache = (Group) myContext.fromCache(Group.class, + Group fromCache = (Group) ourContext.fromCache(Group.class, r.getIntColumn("eperson_group_id")); if (fromCache != null) @@ -168,7 +160,7 @@ public void loadData() } else { - groups.add(new Group(myContext, r)); + groups.add(new Group(ourContext, r)); } } } @@ -237,7 +229,7 @@ public int getID() */ public String getName() { - return myRow.getStringColumn("name"); + return getMetadataFirstValue(MetadataSchema.DC_SCHEMA, "title", null, Item.ANY); } /** @@ -246,11 +238,8 @@ public String getName() * @param name * new group name */ - public void setName(String name) - { - myRow.setColumn("name", name); - modifiedMetadata = true; - addDetails("name"); + public void setName(String name) { + setMetadataSingleValue(MetadataSchema.DC_SCHEMA, "title", null, null, name); } /** @@ -271,9 +260,7 @@ public void addMember(EPerson e) epeople.add(e); epeopleChanged = true; - myContext.addEvent(new Event(Event.ADD, Constants.GROUP, getID(), - Constants.EPERSON, e.getID(), e.getEmail(), - getIdentifiers(myContext))); + ourContext.addEvent(new Event(Event.ADD, Constants.GROUP, getID(), Constants.EPERSON, e.getID(), e.getEmail(), getIdentifiers(ourContext))); } /** @@ -295,9 +282,7 @@ public void addMember(Group g) groups.add(g); groupsChanged = true; - myContext.addEvent(new Event(Event.ADD, Constants.GROUP, getID(), - Constants.GROUP, g.getID(), g.getName(), - getIdentifiers(myContext))); + ourContext.addEvent(new Event(Event.ADD, Constants.GROUP, getID(), Constants.GROUP, g.getID(), g.getName(), getIdentifiers(ourContext))); } /** @@ -313,9 +298,7 @@ public void removeMember(EPerson e) if (epeople.remove(e)) { epeopleChanged = true; - myContext.addEvent(new Event(Event.REMOVE, Constants.GROUP, getID(), - Constants.EPERSON, e.getID(), e.getEmail(), - getIdentifiers(myContext))); + ourContext.addEvent(new Event(Event.REMOVE, Constants.GROUP, getID(), Constants.EPERSON, e.getID(), e.getEmail(), getIdentifiers(ourContext))); } } @@ -331,9 +314,7 @@ public void removeMember(Group g) if (groups.remove(g)) { groupsChanged = true; - myContext.addEvent(new Event(Event.REMOVE, Constants.GROUP, getID(), - Constants.GROUP, g.getID(), g.getName(), - getIdentifiers(myContext))); + ourContext.addEvent(new Event(Event.REMOVE, Constants.GROUP, getID(), Constants.GROUP, g.getID(), g.getName(), getIdentifiers(ourContext))); } } @@ -717,8 +698,20 @@ public static Group find(Context context, int id) throws SQLException public static Group findByName(Context context, String name) throws SQLException { - TableRow row = DatabaseManager.findByUnique(context, "epersongroup", - "name", name); + String query = "select * from epersongroup e " + + "LEFT JOIN metadatavalue m on (m.resource_id = e.eperson_group_id and m.resource_type_id = ? and m.metadata_field_id = ?) " + + "where "; + if(DatabaseManager.isOracle()) { + query += " dbms_lob.substr(m.text_value) = ?"; + }else{ + query += " m.text_value = ?"; + + } + TableRow row = DatabaseManager.querySingle(context, query, + Constants.GROUP, + MetadataField.findByElement(context, MetadataSchema.find(context, MetadataSchema.DC_SCHEMA).getSchemaID(), "title", null).getFieldID(), + name + ); if (row == null) { @@ -759,24 +752,31 @@ public static Group[] findAll(Context context, int sortField) switch (sortField) { case ID: - s = "eperson_group_id"; + s = "e.eperson_group_id"; break; case NAME: - s = "name"; + s = "m_text_value"; break; default: - s = "name"; + s = "m_text_value"; } // NOTE: The use of 's' in the order by clause can not cause an SQL // injection because the string is derived from constant values above. - TableRowIterator rows = DatabaseManager.queryTable( - context, "epersongroup", - "SELECT * FROM epersongroup ORDER BY "+s); + TableRowIterator rows = DatabaseManager.query( + context, + "select e.* from epersongroup e " + + "LEFT JOIN metadatavalue m on (m.resource_id = e.eperson_group_id and m.resource_type_id = ? and m.metadata_field_id = ?) " + + "order by ?", + Constants.GROUP, + MetadataField.findByElement(context, MetadataSchema.find(context, MetadataSchema.DC_SCHEMA).getSchemaID(), "title", null).getFieldID(), + s + ); + try { @@ -849,8 +849,17 @@ public static Group[] search(Context context, String query, int offset, int limi { String params = "%"+query.toLowerCase()+"%"; StringBuffer queryBuf = new StringBuffer(); - queryBuf.append("SELECT * FROM epersongroup WHERE LOWER(name) LIKE LOWER(?) OR eperson_group_id = ? ORDER BY name ASC "); - + queryBuf.append("SELECT * FROM epersongroup " + + "LEFT JOIN metadatavalue m on (m.resource_id = epersongroup.eperson_group_id and m.resource_type_id = ? and m.metadata_field_id = ?) " + + "WHERE LOWER(m.text_value) LIKE LOWER(?) OR eperson_group_id = ? "); + + if(DatabaseManager.isOracle()){ + queryBuf.append(" ORDER BY cast(m.text_value as varchar2(128))"); + }else{ + queryBuf.append(" ORDER BY m.text_value"); + } + queryBuf.append(" ASC"); + // Add offset and limit restrictions - Oracle requires special code if (DatabaseManager.isOracle()) { @@ -904,18 +913,21 @@ public static Group[] search(Context context, String query, int offset, int limi } // Create the parameter array, including limit and offset if part of the query - Object[] paramArr = new Object[]{params, int_param}; + + int metadataFieldId = MetadataField.findByElement(context, MetadataSchema.find(context, MetadataSchema.DC_SCHEMA).getSchemaID(), "title", null).getFieldID(); + + Object[] paramArr = new Object[]{Constants.GROUP, metadataFieldId, params, int_param}; if (limit > 0 && offset > 0) { - paramArr = new Object[]{params, int_param, limit, offset}; + paramArr = new Object[]{Constants.GROUP, metadataFieldId,params, int_param, limit, offset}; } else if (limit > 0) { - paramArr = new Object[]{params, int_param, limit}; + paramArr = new Object[]{Constants.GROUP, metadataFieldId,params, int_param, limit}; } else if (offset > 0) { - paramArr = new Object[]{params, int_param, offset}; + paramArr = new Object[]{Constants.GROUP, metadataFieldId,params, int_param, offset}; } TableRowIterator rows = @@ -969,7 +981,9 @@ public static int searchResultCount(Context context, String query) throws SQLException { String params = "%"+query.toLowerCase()+"%"; - String dbquery = "SELECT count(*) as gcount FROM epersongroup WHERE LOWER(name) LIKE LOWER(?) OR eperson_group_id = ? "; + String dbquery = "SELECT count(*) as gcount FROM epersongroup " + + "LEFT JOIN metadatavalue m on (m.resource_id = epersongroup.eperson_group_id and m.resource_type_id = ? and m.metadata_field_id = ?) " + + "WHERE LOWER(m.text_value) LIKE LOWER(?) OR eperson_group_id = ? "; // When checking against the eperson-id, make sure the query can be made into a number Integer int_param; @@ -981,7 +995,16 @@ public static int searchResultCount(Context context, String query) } // Get all the epeople that match the query - TableRow row = DatabaseManager.querySingle(context, dbquery, new Object[] {params, int_param}); + TableRow row = DatabaseManager.querySingle( + context, + dbquery, + new Object[] { + Constants.GROUP, + MetadataField.findByElement(context, MetadataSchema.find(context, MetadataSchema.DC_SCHEMA).getSchemaID(), "title", null).getFieldID(), + params, + int_param + } + ); // use getIntColumn for Oracle count data Long count; @@ -1006,40 +1029,43 @@ public void delete() throws SQLException { // FIXME: authorizations - myContext.addEvent(new Event(Event.DELETE, Constants.GROUP, getID(), - getName(), getIdentifiers(myContext))); + ourContext.addEvent(new Event(Event.DELETE, Constants.GROUP, getID(), getName(), getIdentifiers(ourContext))); // Remove from cache - myContext.removeCached(this, getID()); + ourContext.removeCached(this, getID()); // Remove any ResourcePolicies that reference this group - AuthorizeManager.removeGroupPolicies(myContext, getID()); + AuthorizeManager.removeGroupPolicies(ourContext, getID()); // Remove any group memberships first - DatabaseManager.updateQuery(myContext, + DatabaseManager.updateQuery(ourContext, "DELETE FROM EPersonGroup2EPerson WHERE eperson_group_id= ? ", getID()); // remove any group2groupcache entries - DatabaseManager.updateQuery(myContext, + DatabaseManager.updateQuery(ourContext, "DELETE FROM group2groupcache WHERE parent_id= ? OR child_id= ? ", getID(),getID()); // Now remove any group2group assignments - DatabaseManager.updateQuery(myContext, + DatabaseManager.updateQuery(ourContext, "DELETE FROM group2group WHERE parent_id= ? OR child_id= ? ", getID(),getID()); + // Delete the Dublin Core + removeMetadataFromDatabase(); + // don't forget the new table deleteEpersonGroup2WorkspaceItem(); // Remove ourself - DatabaseManager.delete(myContext, myRow); + DatabaseManager.delete(ourContext, myRow); epeople.clear(); - log.info(LogManager.getHeader(myContext, "delete_group", "group_id=" + log.info(LogManager.getHeader(ourContext, "delete_group", "group_id=" + getID())); + } /** @@ -1047,7 +1073,7 @@ public void delete() throws SQLException */ private void deleteEpersonGroup2WorkspaceItem() throws SQLException { - DatabaseManager.updateQuery(myContext, + DatabaseManager.updateQuery(ourContext, "DELETE FROM EPersonGroup2WorkspaceItem WHERE eperson_group_id= ? ", getID()); } @@ -1111,13 +1137,11 @@ public boolean isEmpty() public void update() throws SQLException, AuthorizeException { // FIXME: Check authorisation - DatabaseManager.update(myContext, myRow); + DatabaseManager.update(ourContext, myRow); if (modifiedMetadata) { - myContext.addEvent(new Event(Event.MODIFY_METADATA, Constants.GROUP, - getID(), getDetails(), getIdentifiers(myContext))); - modifiedMetadata = false; + updateMetadata(); clearDetails(); } @@ -1125,7 +1149,7 @@ public void update() throws SQLException, AuthorizeException if (epeopleChanged) { // Remove any existing mappings - DatabaseManager.updateQuery(myContext, + DatabaseManager.updateQuery(ourContext, "delete from epersongroup2eperson where eperson_group_id= ? ", getID()); @@ -1139,7 +1163,7 @@ public void update() throws SQLException, AuthorizeException TableRow mappingRow = DatabaseManager.row("epersongroup2eperson"); mappingRow.setColumn("eperson_id", e.getID()); mappingRow.setColumn("eperson_group_id", getID()); - DatabaseManager.insert(myContext, mappingRow); + DatabaseManager.insert(ourContext, mappingRow); } epeopleChanged = false; @@ -1149,7 +1173,7 @@ public void update() throws SQLException, AuthorizeException if (groupsChanged) { // Remove any existing mappings - DatabaseManager.updateQuery(myContext, + DatabaseManager.updateQuery(ourContext, "delete from group2group where parent_id= ? ", getID()); @@ -1163,7 +1187,7 @@ public void update() throws SQLException, AuthorizeException TableRow mappingRow = DatabaseManager.row("group2group"); mappingRow.setColumn("parent_id", getID()); mappingRow.setColumn("child_id", g.getID()); - DatabaseManager.insert(myContext, mappingRow); + DatabaseManager.insert(ourContext, mappingRow); } // groups changed, now change group cache @@ -1172,7 +1196,7 @@ public void update() throws SQLException, AuthorizeException groupsChanged = false; } - log.info(LogManager.getHeader(myContext, "update_group", "group_id=" + log.info(LogManager.getHeader(ourContext, "update_group", "group_id=" + getID())); } @@ -1233,7 +1257,7 @@ public String getHandle() private void rethinkGroupCache() throws SQLException { // read in the group2group table - TableRowIterator tri = DatabaseManager.queryTable(myContext, "group2group", + TableRowIterator tri = DatabaseManager.queryTable(ourContext, "group2group", "SELECT * FROM group2group"); Map> parents = new HashMap>(); @@ -1286,7 +1310,7 @@ private void rethinkGroupCache() throws SQLException } // empty out group2groupcache table - DatabaseManager.updateQuery(myContext, + DatabaseManager.updateQuery(ourContext, "DELETE FROM group2groupcache WHERE id >= 0"); // write out new one @@ -1301,7 +1325,7 @@ private void rethinkGroupCache() throws SQLException row.setColumn("parent_id", parentID); row.setColumn("child_id", child); - DatabaseManager.insert(myContext, row); + DatabaseManager.insert(ourContext, row); } } } @@ -1365,7 +1389,7 @@ public DSpaceObject getParentObject() throws SQLException // is this a collection related group? TableRow qResult = DatabaseManager .querySingle( - myContext, + ourContext, "SELECT collection_id, workflow_step_1, workflow_step_2, " + " workflow_step_3, submitter, admin FROM collection " + " WHERE workflow_step_1 = ? OR " @@ -1375,7 +1399,7 @@ public DSpaceObject getParentObject() throws SQLException getID(), getID(), getID(), getID(), getID()); if (qResult != null) { - Collection collection = Collection.find(myContext, qResult + Collection collection = Collection.find(ourContext, qResult .getIntColumn("collection_id")); if ((qResult.getIntColumn("workflow_step_1") == getID() || @@ -1418,13 +1442,13 @@ else if (AuthorizeConfiguration.canCommunityAdminManageCollectionAdminGroup()) // to manage it? else if (AuthorizeConfiguration.canCommunityAdminManageAdminGroup()) { - qResult = DatabaseManager.querySingle(myContext, + qResult = DatabaseManager.querySingle(ourContext, "SELECT community_id FROM community " + "WHERE admin = ?", getID()); if (qResult != null) { - Community community = Community.find(myContext, qResult + Community community = Community.find(ourContext, qResult .getIntColumn("community_id")); return community; } @@ -1438,4 +1462,37 @@ public void updateLastModified() { } + + /** + * Main script used to set the group names for anonymous group & admin group, only to be called once on DSpace fresh_install + * @param args not used + * @throws SQLException database exception + * @throws AuthorizeException should not occur since we disable authentication for this method. + */ + public static void main(String[] args) throws SQLException, AuthorizeException { + Context context = new Context(); + context.turnOffAuthorisationSystem(); + + initDefaultGroupNames(context); + + //Clear the events to avoid the consumers which aren't needed at this time + context.getEvents().clear(); + context.complete(); + } + + /** + * Initializes the group names for anymous & administrator + * @param context the dspace context + * @throws SQLException database exception + * @throws AuthorizeException + */ + public static void initDefaultGroupNames(Context context) throws SQLException, AuthorizeException { + Group anonymousGroup = Group.find(context, 0); + anonymousGroup.setName("Anonymous"); + anonymousGroup.update(); + + Group adminGroup = Group.find(context, 1); + adminGroup.setName("Administrator"); + adminGroup.update(); + } } diff --git a/dspace-api/src/main/java/org/dspace/identifier/EZIDIdentifierProvider.java b/dspace-api/src/main/java/org/dspace/identifier/EZIDIdentifierProvider.java index 50f4cc74a654..ae49182785a6 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/EZIDIdentifierProvider.java +++ b/dspace-api/src/main/java/org/dspace/identifier/EZIDIdentifierProvider.java @@ -629,7 +629,7 @@ private Map crosswalkMetadata(DSpaceObject dso) for (Entry datum : crosswalk.entrySet()) { - DCValue[] values = item.getMetadata(datum.getValue()); + DCValue[] values = item.getMetadataByMetadataString(datum.getValue()); if (null != values) { for (DCValue value : values) diff --git a/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseManager.java b/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseManager.java index 96eb56a19363..5d47d1829593 100644 --- a/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseManager.java +++ b/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseManager.java @@ -114,16 +114,17 @@ public static boolean isOracle() * @throws SQLException */ public static void setConstraintDeferred(Context context, - String constraintName) throws SQLException - { + String constraintName) throws SQLException { Statement statement = null; try { statement = context.getDBConnection().createStatement(); statement.execute("SET CONSTRAINTS " + constraintName + " DEFERRED"); statement.close(); - } - finally + } catch (SQLException e) { + log.error("SQL setConstraintDeferred Error - ", e); + throw e; + } finally { if (statement != null) { @@ -133,6 +134,8 @@ public static void setConstraintDeferred(Context context, } catch (SQLException sqle) { + log.error("SQL setConstraintDeferred close Error - ",sqle); + throw sqle; } } } @@ -148,16 +151,17 @@ public static void setConstraintDeferred(Context context, * @throws SQLException */ public static void setConstraintImmediate(Context context, - String constraintName) throws SQLException - { + String constraintName) throws SQLException { Statement statement = null; try { statement = context.getDBConnection().createStatement(); statement.execute("SET CONSTRAINTS " + constraintName + " IMMEDIATE"); statement.close(); - } - finally + } catch (SQLException e) { + log.error("SQL setConstraintImmediate Error - ", e); + throw e; + } finally { if (statement != null) { @@ -167,6 +171,8 @@ public static void setConstraintImmediate(Context context, } catch (SQLException sqle) { + log.error("SQL setConstraintImmediate Error - ",sqle); + throw sqle; } } } @@ -191,8 +197,7 @@ public static void setConstraintImmediate(Context context, * @exception SQLException * If a database error occurs */ - public static TableRowIterator queryTable(Context context, String table, String query, Object... parameters ) throws SQLException - { + public static TableRowIterator queryTable(Context context, String table, String query, Object... parameters ) throws SQLException { if (log.isDebugEnabled()) { StringBuilder sb = new StringBuilder("Running query \"").append(query).append("\" with parameters: "); @@ -207,9 +212,11 @@ public static TableRowIterator queryTable(Context context, String table, String log.debug(sb.toString()); } - PreparedStatement statement = context.getDBConnection().prepareStatement(query); + PreparedStatement statement = null; try { + statement = context.getDBConnection().prepareStatement(query); + loadParameters(statement, parameters); TableRowIterator retTRI = new TableRowIterator(statement.executeQuery(), canonicalize(table)); @@ -227,9 +234,11 @@ public static TableRowIterator queryTable(Context context, String table, String } catch (SQLException s) { + log.error("SQL QueryTable close Error - ",s); + throw s; } } - + log.error("SQL QueryTable Error - ",sqle); throw sqle; } } @@ -286,9 +295,11 @@ public static TableRowIterator query(Context context, String query, } catch (SQLException s) { + log.error("SQL query exec close Error - ",s); + throw s; } } - + log.error("SQL query exec Error - ",sqle); throw sqle; } } @@ -311,16 +322,17 @@ public static TableRowIterator query(Context context, String query, * If a database error occurs */ public static TableRow querySingle(Context context, String query, - Object... parameters) throws SQLException - { + Object... parameters) throws SQLException { TableRow retRow = null; TableRowIterator iterator = null; try { iterator = query(context, query, parameters); retRow = (!iterator.hasNext()) ? null : iterator.next(); - } - finally + } catch (SQLException e) { + log.error("SQL query single Error - ", e); + throw e; + } finally { if (iterator != null) { @@ -350,16 +362,23 @@ public static TableRow querySingle(Context context, String query, * If a database error occurs */ public static TableRow querySingleTable(Context context, String table, - String query, Object... parameters) throws SQLException - { + String query, Object... parameters) throws SQLException { TableRow retRow = null; - TableRowIterator iterator = queryTable(context, canonicalize(table), query, parameters); + TableRowIterator iterator = null; + try { + iterator = queryTable(context, canonicalize(table), query, parameters); + } catch (SQLException e) { + log.error("SQL query singleTable Error - ", e); + throw e; + } try { retRow = (!iterator.hasNext()) ? null : iterator.next(); - } - finally + } catch (SQLException e) { + log.error("SQL query singleTable Error - ", e); + throw e; + } finally { if (iterator != null) { @@ -385,8 +404,7 @@ public static TableRow querySingleTable(Context context, String table, * @exception SQLException * If a database error occurs */ - public static int updateQuery(Context context, String query, Object... parameters) throws SQLException - { + public static int updateQuery(Context context, String query, Object... parameters) throws SQLException { PreparedStatement statement = null; if (log.isDebugEnabled()) @@ -409,8 +427,10 @@ public static int updateQuery(Context context, String query, Object... parameter loadParameters(statement, parameters); return statement.executeUpdate(); - } - finally + } catch (SQLException e) { + log.error("SQL query updateQuery Error - ", e); + throw e; + } finally { if (statement != null) { @@ -420,6 +440,8 @@ public static int updateQuery(Context context, String query, Object... parameter } catch (SQLException sqle) { + log.error("SQL updateQuery Error - ",sqle); + throw sqle; } } } @@ -434,13 +456,17 @@ public static int updateQuery(Context context, String query, Object... parameter * The RDBMS table in which to create the new row * @return The newly created row */ - public static TableRow create(Context context, String table) - throws SQLException - { - TableRow row = new TableRow(canonicalize(table), getColumnNames(table)); - insert(context, row); + public static TableRow create(Context context, String table) throws SQLException - return row; + { + try { + TableRow row = new TableRow(canonicalize(table), getColumnNames(table)); + insert(context, row); + return row; + } catch (SQLException e) { + log.error("SQL create Error - ",e); + throw e; + } } /** @@ -458,13 +484,18 @@ public static TableRow create(Context context, String table) * @exception SQLException * If a database error occurs */ - public static TableRow find(Context context, String table, int id) - throws SQLException + public static TableRow find(Context context, String table, int id) throws SQLException + { String ctable = canonicalize(table); - return findByUnique(context, ctable, getPrimaryKeyColumn(ctable), - Integer.valueOf(id)); + try { + return findByUnique(context, ctable, getPrimaryKeyColumn(ctable), + Integer.valueOf(id)); + } catch (SQLException e) { + log.error("SQL find Error - ", e); + throw e; + } } /** @@ -486,22 +517,25 @@ public static TableRow find(Context context, String table, int id) * If a database error occurs */ public static TableRow findByUnique(Context context, String table, - String column, Object value) throws SQLException - { + String column, Object value) throws SQLException { String ctable = canonicalize(table); - if ( ! DB_SAFE_NAME.matcher(ctable).matches()) - { - throw new SQLException("Unable to execute select query because table name (" + ctable + ") contains non alphanumeric characters."); - } + try { + if ( ! DB_SAFE_NAME.matcher(ctable).matches()) + { + throw new SQLException("Unable to execute select query because table name (" + ctable + ") contains non alphanumeric characters."); + } - if ( ! DB_SAFE_NAME.matcher(column).matches()) - { - throw new SQLException("Unable to execute select query because column name (" + column + ") contains non alphanumeric characters."); + if ( ! DB_SAFE_NAME.matcher(column).matches()) + { + throw new SQLException("Unable to execute select query because column name (" + column + ") contains non alphanumeric characters."); + } + StringBuilder sql = new StringBuilder("select * from ").append(ctable).append(" where ").append(column).append(" = ? "); + return querySingleTable(context, ctable, sql.toString(), value); + } catch (SQLException e) { + log.error("SQL findByUnique Error - ", e); + throw e; } - - StringBuilder sql = new StringBuilder("select * from ").append(ctable).append(" where ").append(column).append(" = ? "); - return querySingleTable(context, ctable, sql.toString(), value); } /** @@ -518,13 +552,16 @@ public static TableRow findByUnique(Context context, String table, * @exception SQLException * If a database error occurs */ - public static int delete(Context context, String table, int id) - throws SQLException + public static int delete(Context context, String table, int id) throws SQLException { - String ctable = canonicalize(table); - - return deleteByValue(context, ctable, getPrimaryKeyColumn(ctable), - Integer.valueOf(id)); + try { + String ctable = canonicalize(table); + return deleteByValue(context, ctable, getPrimaryKeyColumn(ctable), + Integer.valueOf(id)); + } catch (SQLException e) { + log.error("SQL delete Error - ", e); + throw e; + } } /** @@ -546,20 +583,25 @@ public static int delete(Context context, String table, int id) public static int deleteByValue(Context context, String table, String column, Object value) throws SQLException { - String ctable = canonicalize(table); + try { + String ctable = canonicalize(table); - if ( ! DB_SAFE_NAME.matcher(ctable).matches()) - { - throw new SQLException("Unable to execute delete query because table name (" + ctable + ") contains non alphanumeric characters."); - } + if ( ! DB_SAFE_NAME.matcher(ctable).matches()) + { + throw new SQLException("Unable to execute delete query because table name (" + ctable + ") contains non alphanumeric characters."); + } - if ( ! DB_SAFE_NAME.matcher(column).matches()) - { - throw new SQLException("Unable to execute delete query because column name (" + column + ") contains non alphanumeric characters."); - } + if ( ! DB_SAFE_NAME.matcher(column).matches()) + { + throw new SQLException("Unable to execute delete query because column name (" + column + ") contains non alphanumeric characters."); + } - StringBuilder sql = new StringBuilder("delete from ").append(ctable).append(" where ").append(column).append(" = ? "); - return updateQuery(context, sql.toString(), value); + StringBuilder sql = new StringBuilder("delete from ").append(ctable).append(" where ").append(column).append(" = ? "); + return updateQuery(context, sql.toString(), value); + } catch (SQLException e) { + log.error("SQL deleteByValue Error - ", e); + throw e; + } } /** @@ -572,15 +614,20 @@ public static int deleteByValue(Context context, String table, */ public static Connection getConnection() throws SQLException { - initialize(); + try{ + initialize(); - if (dataSource != null) { - Connection conn = dataSource.getConnection(); + if (dataSource != null) { + Connection conn = dataSource.getConnection(); - return conn; - } + return conn; + } - return null; + return null; + } catch (SQLException e) { + log.error("SQL connection Error - ", e); + throw e; + } } public static DataSource getDataSource() @@ -591,6 +638,7 @@ public static DataSource getDataSource() } catch (SQLException e) { + log.error("SQL getDataSource Error - ",e); throw new IllegalStateException(e.getMessage(), e); } @@ -855,6 +903,7 @@ public static void loadSql(String sql) throws SQLException } catch (IOException ioe) { + log.error("IOE loadSQL Error - ",ioe); } } @@ -1267,6 +1316,8 @@ private static void execute(Connection connection, String sql, Collection0) ) + if( (item.getMetadataByMetadataString("dc.type") != null) && (item.getMetadataByMetadataString("dc.type").length >0) ) { - documentType = item.getMetadata("dc.type")[0].value; + documentType = item.getMetadataByMetadataString("dc.type")[0].value; } // Step 1: diff --git a/dspace-api/src/test/java/org/dspace/AbstractUnitTest.java b/dspace-api/src/test/java/org/dspace/AbstractUnitTest.java index 9a97abca024a..671d27cceb55 100644 --- a/dspace-api/src/test/java/org/dspace/AbstractUnitTest.java +++ b/dspace-api/src/test/java/org/dspace/AbstractUnitTest.java @@ -36,6 +36,7 @@ import org.dspace.discovery.IndexingService; import org.dspace.discovery.MockIndexEventConsumer; import org.dspace.eperson.EPerson; +import org.dspace.eperson.Group; import org.dspace.servicemanager.DSpaceKernelImpl; import org.dspace.servicemanager.DSpaceKernelInit; import org.dspace.storage.rdbms.DatabaseManager; @@ -148,6 +149,8 @@ public static void initOnce() RegistryLoader.loadBitstreamFormats(ctx, base + "bitstream-formats.xml"); MetadataImporter.loadRegistry(base + "dublin-core-types.xml", true); + MetadataImporter.loadRegistry(base + "eperson-types.xml", true); + MetadataImporter.loadRegistry(base + "bitstream-formats.xml", true); MetadataImporter.loadRegistry(base + "sword-metadata.xml", true); ctx.commit(); @@ -173,6 +176,7 @@ public static void initOnce() dspace = null; indexer = null; } + Group.initDefaultGroupNames(ctx); ctx.restoreAuthSystemState(); if(ctx.isValid()) { diff --git a/dspace-api/src/test/java/org/dspace/content/CollectionTest.java b/dspace-api/src/test/java/org/dspace/content/CollectionTest.java index ea4c90ee5052..9750463878db 100644 --- a/dspace-api/src/test/java/org/dspace/content/CollectionTest.java +++ b/dspace-api/src/test/java/org/dspace/content/CollectionTest.java @@ -222,9 +222,7 @@ public void testGetMetadata() assertThat("testGetMetadata 0",c.getMetadata("name"), equalTo("")); assertThat("testGetMetadata 1",c.getMetadata("short_description"), equalTo("")); assertThat("testGetMetadata 2",c.getMetadata("introductory_text"), equalTo("")); - assertThat("testGetMetadata 3",c.getMetadata("logo_bitstream_id"), equalTo("")); assertThat("testGetMetadata 4",c.getMetadata("copyright_text"), equalTo("")); - assertThat("testGetMetadata 5",c.getMetadata("template_item_id"), equalTo("")); assertThat("testGetMetadata 6",c.getMetadata("provenance_description"), equalTo("")); assertThat("testGetMetadata 7",c.getMetadata("side_bar_text"), equalTo("")); assertThat("testGetMetadata 8",c.getMetadata("license"), equalTo("")); @@ -234,12 +232,10 @@ public void testGetMetadata() * Test of setMetadata method, of class Collection. */ @Test - public void testSetMetadata() - { + public void testSetMetadata() throws SQLException { String name = "name"; String sdesc = "short description"; String itext = "introductory text"; - String logo = "1"; String copy = "copyright declaration"; String sidebar = "side bar text"; String tempItem = "3"; @@ -249,20 +245,16 @@ public void testSetMetadata() c.setMetadata("name", name); c.setMetadata("short_description", sdesc); c.setMetadata("introductory_text", itext); - c.setMetadata("logo_bitstream_id", logo); c.setMetadata("copyright_text", copy); c.setMetadata("side_bar_text", sidebar); - c.setMetadata("template_item_id", tempItem); c.setMetadata("provenance_description", provDesc); c.setMetadata("license", license); assertThat("testSetMetadata 0",c.getMetadata("name"), equalTo(name)); assertThat("testSetMetadata 1",c.getMetadata("short_description"), equalTo(sdesc)); assertThat("testSetMetadata 2",c.getMetadata("introductory_text"), equalTo(itext)); - assertThat("testSetMetadata 3",c.getMetadata("logo_bitstream_id"), equalTo(logo)); assertThat("testSetMetadata 4",c.getMetadata("copyright_text"), equalTo(copy)); assertThat("testSetMetadata 5",c.getMetadata("side_bar_text"), equalTo(sidebar)); - assertThat("testGetMetadata 6",c.getMetadata("template_item_id"), equalTo(tempItem)); assertThat("testGetMetadata 7",c.getMetadata("provenance_description"), equalTo(provDesc)); assertThat("testGetMetadata 8",c.getMetadata("license"), equalTo(license)); } @@ -689,8 +681,7 @@ public void testHasCustomLicense() * Test of setLicense method, of class Collection. */ @Test - public void testSetLicense() - { + public void testSetLicense() throws SQLException { String license = "license for test"; c.setLicense(license); assertThat("testSetLicense 0", c.getLicense(), notNullValue()); @@ -1880,4 +1871,4 @@ public void testGetParentObject() throws SQLException } } -} \ No newline at end of file +} diff --git a/dspace-api/src/test/java/org/dspace/content/CommunityTest.java b/dspace-api/src/test/java/org/dspace/content/CommunityTest.java index 918cca5b9176..6f6a00ff08a4 100644 --- a/dspace-api/src/test/java/org/dspace/content/CommunityTest.java +++ b/dspace-api/src/test/java/org/dspace/content/CommunityTest.java @@ -334,7 +334,6 @@ public void testGetMetadata() assertThat("testGetMetadata 0",c.getMetadata("name"), equalTo("")); assertThat("testGetMetadata 1",c.getMetadata("short_description"), equalTo("")); assertThat("testGetMetadata 2",c.getMetadata("introductory_text"), equalTo("")); - assertThat("testGetMetadata 3",c.getMetadata("logo_bitstream_id"), equalTo("")); assertThat("testGetMetadata 4",c.getMetadata("copyright_text"), equalTo("")); assertThat("testGetMetadata 5",c.getMetadata("side_bar_text"), equalTo("")); } @@ -348,21 +347,18 @@ public void testSetMetadata() String name = "name"; String sdesc = "short description"; String itext = "introductory text"; - String logo = "1"; String copy = "copyright declaration"; String sidebar = "side bar text"; c.setMetadata("name", name); c.setMetadata("short_description", sdesc); c.setMetadata("introductory_text", itext); - c.setMetadata("logo_bitstream_id", logo); c.setMetadata("copyright_text", copy); c.setMetadata("side_bar_text", sidebar); assertThat("testSetMetadata 0",c.getMetadata("name"), equalTo(name)); assertThat("testSetMetadata 1",c.getMetadata("short_description"), equalTo(sdesc)); assertThat("testSetMetadata 2",c.getMetadata("introductory_text"), equalTo(itext)); - assertThat("testSetMetadata 3",c.getMetadata("logo_bitstream_id"), equalTo(logo)); assertThat("testSetMetadata 4",c.getMetadata("copyright_text"), equalTo(copy)); assertThat("testSetMetadata 5",c.getMetadata("side_bar_text"), equalTo(sidebar)); } diff --git a/dspace-api/src/test/java/org/dspace/content/ItemTest.java b/dspace-api/src/test/java/org/dspace/content/ItemTest.java index 251c397865a8..b2035557ba52 100644 --- a/dspace-api/src/test/java/org/dspace/content/ItemTest.java +++ b/dspace-api/src/test/java/org/dspace/content/ItemTest.java @@ -9,7 +9,6 @@ import java.io.File; import java.io.FileInputStream; -import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.sql.SQLException; @@ -294,23 +293,23 @@ public void testGetMetadata_4args() } /** - * Test of getMetadata method, of class Item. + * Test of getMetadataByMetadataString method, of class Item. */ @Test public void testGetMetadata_String() { String mdString = "dc.contributor.author"; - DCValue[] dc = it.getMetadata(mdString); + DCValue[] dc = it.getMetadataByMetadataString(mdString); assertThat("testGetMetadata_String 0",dc,notNullValue()); assertTrue("testGetMetadata_String 1",dc.length == 0); mdString = "dc.contributor.*"; - dc = it.getMetadata(mdString); + dc = it.getMetadataByMetadataString(mdString); assertThat("testGetMetadata_String 2",dc,notNullValue()); assertTrue("testGetMetadata_String 3",dc.length == 0); mdString = "dc.contributor"; - dc = it.getMetadata(mdString); + dc = it.getMetadataByMetadataString(mdString); assertThat("testGetMetadata_String 4",dc,notNullValue()); assertTrue("testGetMetadata_String 5",dc.length == 0); } diff --git a/dspace-api/src/test/java/org/dspace/content/MetadataFieldTest.java b/dspace-api/src/test/java/org/dspace/content/MetadataFieldTest.java index e59331982647..8d4a8d94c38e 100644 --- a/dspace-api/src/test/java/org/dspace/content/MetadataFieldTest.java +++ b/dspace-api/src/test/java/org/dspace/content/MetadataFieldTest.java @@ -65,11 +65,6 @@ public void init() MetadataSchema.DC_SCHEMA_ID, element, qualifier); this.mf.setScopeNote(scopeNote); } - catch (AuthorizeException ex) - { - log.error("Authorize Error in init", ex); - fail("Authorize Error in init: " + ex.getMessage()); - } catch (SQLException ex) { log.error("SQL Error in init", ex); @@ -451,4 +446,4 @@ public void testFind() throws Exception assertThat("testFind 1",found.getFieldID(), equalTo(mf.getFieldID())); } -} \ No newline at end of file +} diff --git a/dspace-api/src/test/java/org/dspace/content/MetadataIntegrationTest.java b/dspace-api/src/test/java/org/dspace/content/MetadataIntegrationTest.java index 07235df2eaad..926ab76e4572 100644 --- a/dspace-api/src/test/java/org/dspace/content/MetadataIntegrationTest.java +++ b/dspace-api/src/test/java/org/dspace/content/MetadataIntegrationTest.java @@ -16,6 +16,7 @@ import org.apache.log4j.Logger; import org.dspace.AbstractIntegrationTest; import org.dspace.authorize.AuthorizeException; +import org.dspace.core.Constants; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -84,12 +85,14 @@ public void testCreateSchema() throws SQLException, AuthorizeException, NonUniqu field2.create(context); MetadataValue value1 = new MetadataValue(field1); - value1.setItemId(it.getID()); + value1.setResourceId(it.getID()); + value1.setResourceTypeId(Constants.ITEM); value1.setValue("value1"); value1.create(context); MetadataValue value2 = new MetadataValue(field2); - value2.setItemId(it.getID()); + value2.setResourceId(it.getID()); + value2.setResourceTypeId(Constants.ITEM); value2.setValue("value2"); value2.create(context); diff --git a/dspace-api/src/test/java/org/dspace/content/MetadataValueTest.java b/dspace-api/src/test/java/org/dspace/content/MetadataValueTest.java index 6c3e7aad0259..322d5f88aa86 100644 --- a/dspace-api/src/test/java/org/dspace/content/MetadataValueTest.java +++ b/dspace-api/src/test/java/org/dspace/content/MetadataValueTest.java @@ -14,6 +14,7 @@ import org.dspace.AbstractUnitTest; import org.apache.log4j.Logger; import org.dspace.authorize.AuthorizeException; +import org.dspace.core.Constants; import org.junit.*; import static org.junit.Assert.* ; import static org.hamcrest.CoreMatchers.*; @@ -66,7 +67,8 @@ public void init() this.mf = MetadataField.findByElement(context, MetadataSchema.DC_SCHEMA_ID, element, qualifier); this.mv = new MetadataValue(mf); - this.mv.setItemId(Item.create(context).getID()); + this.mv.setResourceId(Item.create(context).getID()); + this.mv.setResourceTypeId(Constants.ITEM); context.commit(); context.restoreAuthSystemState(); } @@ -127,7 +129,7 @@ public void testSetFieldId() @Test public void testGetItemId() { - assertTrue("testGetItemId 0", mv.getItemId() >= 0); + assertTrue("testGetItemId 0", mv.getResourceId() >= 0); } /** @@ -137,8 +139,9 @@ public void testGetItemId() public void testSetItemId() { int itemId = 55; - mv.setItemId(itemId); - assertThat("testSetItemId 0", mv.getItemId(), equalTo(itemId)); + mv.setResourceId(itemId); + mv.setResourceTypeId(Constants.ITEM); + assertThat("testSetItemId 0", mv.getResourceId(), equalTo(itemId)); } /** @@ -308,4 +311,4 @@ public void testDelete() throws Exception assertThat("testDelete 0",found, nullValue()); } -} \ No newline at end of file +} diff --git a/dspace-api/src/test/resources/database_schema.sql b/dspace-api/src/test/resources/database_schema.sql index b959e219c8d1..27aa726902b3 100644 --- a/dspace-api/src/test/resources/database_schema.sql +++ b/dspace-api/src/test/resources/database_schema.sql @@ -152,13 +152,9 @@ CREATE TABLE Bitstream ( bitstream_id INTEGER PRIMARY KEY, bitstream_format_id INTEGER REFERENCES BitstreamFormatRegistry(bitstream_format_id), - name VARCHAR(256), size_bytes BIGINT, checksum VARCHAR(64), checksum_algorithm VARCHAR(32), - description TEXT, - user_format_description TEXT, - source VARCHAR(256), internal_id VARCHAR(256), deleted BOOL, store_number INTEGER, @@ -175,16 +171,11 @@ CREATE TABLE EPerson eperson_id INTEGER PRIMARY KEY, email VARCHAR(64), password VARCHAR(64), - firstname VARCHAR(64), - lastname VARCHAR(64), can_log_in BOOL, require_certificate BOOL, self_registered BOOL, last_active TIMESTAMP, - sub_frequency INTEGER, - phone VARCHAR(32), - netid VARCHAR(64), - language VARCHAR(64) + sub_frequency INTEGER ); -- index by email @@ -198,8 +189,7 @@ CREATE INDEX eperson_netid_idx ON EPerson(netid); ------------------------------------------------------- CREATE TABLE EPersonGroup ( - eperson_group_id INTEGER PRIMARY KEY, - name VARCHAR(256) + eperson_group_id INTEGER PRIMARY KEY ); ------------------------------------------------------ @@ -256,7 +246,6 @@ CREATE INDEX item_submitter_fk_idx ON Item(submitter_id); CREATE TABLE Bundle ( bundle_id INTEGER PRIMARY KEY, - name VARCHAR(16), primary_bitstream_id INTEGER REFERENCES Bitstream(bitstream_id) ); @@ -315,7 +304,8 @@ CREATE TABLE MetadataFieldRegistry CREATE TABLE MetadataValue ( metadata_value_id INTEGER PRIMARY KEY, - item_id INTEGER REFERENCES Item(item_id), + resource_id INTEGER NOT NULL, + resource_type_id INTEGER NOT NULL, metadata_field_id INTEGER REFERENCES MetadataFieldRegistry(metadata_field_id), text_value TEXT, text_lang VARCHAR(24), @@ -325,19 +315,17 @@ CREATE TABLE MetadataValue ); -- Create a dcvalue view for backwards compatibilty -CREATE VIEW dcvalue AS - SELECT MetadataValue.metadata_value_id AS "dc_value_id", MetadataValue.item_id, +CREATE VIEW dcvalue AS + SELECT MetadataValue.metadata_value_id AS "dc_value_id", MetadataValue.resource_id, MetadataValue.metadata_field_id AS "dc_type_id", MetadataValue.text_value, MetadataValue.text_lang, MetadataValue.place FROM MetadataValue, MetadataFieldRegistry WHERE MetadataValue.metadata_field_id = MetadataFieldRegistry.metadata_field_id - AND MetadataFieldRegistry.metadata_schema_id = 1; + AND MetadataFieldRegistry.metadata_schema_id = 1 AND MetadataValue.resource_type_id = 2; -- An index for item_id - almost all access is based on -- instantiating the item object, which grabs all values -- related to that item -CREATE INDEX metadatavalue_item_idx ON MetadataValue(item_id); -CREATE INDEX metadatavalue_item_idx2 ON MetadataValue(item_id,metadata_field_id); CREATE INDEX metadatavalue_field_fk_idx ON MetadataValue(metadata_field_id); CREATE INDEX metadatafield_schema_idx ON MetadataFieldRegistry(metadata_schema_id); @@ -347,12 +335,7 @@ CREATE INDEX metadatafield_schema_idx ON MetadataFieldRegistry(metadata_schema_i CREATE TABLE Community ( community_id INTEGER PRIMARY KEY, - name VARCHAR(128), - short_description VARCHAR(512), - introductory_text TEXT, logo_bitstream_id INTEGER REFERENCES Bitstream(bitstream_id), - copyright_text TEXT, - side_bar_text TEXT, admin INTEGER REFERENCES EPersonGroup( eperson_group_id ) ); @@ -365,15 +348,8 @@ CREATE INDEX community_admin_fk_idx ON Community(admin); CREATE TABLE Collection ( collection_id INTEGER PRIMARY KEY, - name VARCHAR(128), - short_description VARCHAR(512), - introductory_text TEXT, logo_bitstream_id INTEGER REFERENCES Bitstream(bitstream_id), template_item_id INTEGER REFERENCES Item(item_id), - provenance_description TEXT, - license TEXT, - copyright_text TEXT, - side_bar_text TEXT, workflow_step_1 INTEGER REFERENCES EPersonGroup( eperson_group_id ), workflow_step_2 INTEGER REFERENCES EPersonGroup( eperson_group_id ), workflow_step_3 INTEGER REFERENCES EPersonGroup( eperson_group_id ), @@ -632,8 +608,8 @@ CREATE TABLE community_item_count ( -- and administrators ------------------------------------------------------- -- We don't use getnextid() for 'anonymous' since the sequences start at '1' -INSERT INTO epersongroup VALUES(0, 'Anonymous'); -INSERT INTO epersongroup VALUES(NEXTVAL('epersongroup_seq'), 'Administrator'); +INSERT INTO epersongroup VALUES(0); +INSERT INTO epersongroup VALUES(NEXTVAL('epersongroup_seq')); ------------------------------------------------------- diff --git a/dspace-jspui/src/main/java/org/dspace/app/webui/jsptag/BrowseListTag.java b/dspace-jspui/src/main/java/org/dspace/app/webui/jsptag/BrowseListTag.java index 3de8495938d3..275d3694a08b 100644 --- a/dspace-jspui/src/main/java/org/dspace/app/webui/jsptag/BrowseListTag.java +++ b/dspace-jspui/src/main/java/org/dspace/app/webui/jsptag/BrowseListTag.java @@ -624,12 +624,7 @@ else if (field.equals(titleField)){ catch (IOException ie) { throw new JspException(ie); - } - catch (SQLException e) - { - throw new JspException(e); - } - catch (BrowseException e) + } catch (BrowseException e) { throw new JspException(e); } diff --git a/dspace-jspui/src/main/java/org/dspace/app/webui/util/MetadataStyleSelection.java b/dspace-jspui/src/main/java/org/dspace/app/webui/util/MetadataStyleSelection.java index d15dd509ebac..33aae9f874c8 100644 --- a/dspace-jspui/src/main/java/org/dspace/app/webui/util/MetadataStyleSelection.java +++ b/dspace-jspui/src/main/java/org/dspace/app/webui/util/MetadataStyleSelection.java @@ -34,7 +34,7 @@ public class MetadataStyleSelection extends AKeyBasedStyleSelection public String getStyleForItem(Item item) throws SQLException { String metadata = ConfigurationManager.getProperty("webui.itemdisplay.metadata-style"); - DCValue[] value = item.getMetadata(metadata); + DCValue[] value = item.getMetadataByMetadataString(metadata); String styleName = "default"; if (value.length > 0) { diff --git a/dspace-jspui/src/main/webapp/dspace-admin/curate-item.jsp b/dspace-jspui/src/main/webapp/dspace-admin/curate-item.jsp index 9713795d65b5..0aa109301820 100644 --- a/dspace-jspui/src/main/webapp/dspace-admin/curate-item.jsp +++ b/dspace-jspui/src/main/webapp/dspace-admin/curate-item.jsp @@ -40,7 +40,7 @@ String title = "Unknown Item"; if (item != null) { - DCValue[] dcvs = item.getMetadata("dc.title"); + DCValue[] dcvs = item.getMetadataByMetadataString("dc.title"); if (dcvs != null && dcvs.length > 0) { title = dcvs[0].value; diff --git a/dspace-jspui/src/main/webapp/submit/edit-metadata.jsp b/dspace-jspui/src/main/webapp/submit/edit-metadata.jsp index aac949f7ac7a..a16b8e2141b5 100644 --- a/dspace-jspui/src/main/webapp/submit/edit-metadata.jsp +++ b/dspace-jspui/src/main/webapp/submit/edit-metadata.jsp @@ -1188,9 +1188,9 @@ // Fetch the document type (dc.type) String documentType = ""; - if( (item.getMetadata("dc.type") != null) && (item.getMetadata("dc.type").length >0) ) + if( (item.getMetadataByMetadataString("dc.type") != null) && (item.getMetadataByMetadataString("dc.type").length >0) ) { - documentType = item.getMetadata("dc.type")[0].value; + documentType = item.getMetadataByMetadataString("dc.type")[0].value; } %> diff --git a/dspace-jspui/src/main/webapp/tools/curate-item.jsp b/dspace-jspui/src/main/webapp/tools/curate-item.jsp index 2898b993eaf5..8210b45f0378 100644 --- a/dspace-jspui/src/main/webapp/tools/curate-item.jsp +++ b/dspace-jspui/src/main/webapp/tools/curate-item.jsp @@ -40,7 +40,7 @@ String title = "Unknown Item"; if (item != null) { - DCValue[] dcvs = item.getMetadata("dc.title"); + DCValue[] dcvs = item.getMetadataByMetadataString("dc.title"); if (dcvs != null && dcvs.length > 0) { title = dcvs[0].value; diff --git a/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceAtLeastOneMetadataFilter.java b/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceAtLeastOneMetadataFilter.java index 9aae449c2112..8656107048a7 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceAtLeastOneMetadataFilter.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceAtLeastOneMetadataFilter.java @@ -18,6 +18,7 @@ import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.apache.solr.client.solrj.util.ClientUtils; +import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.xoai.data.DSpaceItem; import org.dspace.xoai.exceptions.InvalidMetadataFieldException; @@ -154,7 +155,7 @@ private DatabaseFilterResult getWhere(int mdid, List values) { for (String v : values) this.buildWhere(v, parts, params); if (parts.size() > 0) { - String query = "EXISTS (SELECT tmp.* FROM metadatavalue tmp WHERE tmp.item_id=i.item_id AND tmp.metadata_field_id=?" + String query = "EXISTS (SELECT tmp.* FROM metadatavalue tmp WHERE tmp.resource_id=i.item_id AND tmp.resource_type_id=" + Constants.ITEM+ " AND tmp.metadata_field_id=?" + " AND (" + StringUtils.join(parts.iterator(), " OR ") + "))"; diff --git a/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceMetadataExistsFilter.java b/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceMetadataExistsFilter.java index 51ca09f95293..73a36f8d4f9d 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceMetadataExistsFilter.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceMetadataExistsFilter.java @@ -12,6 +12,7 @@ import com.lyncode.xoai.dataprovider.xml.xoaiconfig.parameters.SimpleType; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; +import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.xoai.data.DSpaceItem; import org.dspace.xoai.exceptions.InvalidMetadataFieldException; @@ -72,7 +73,7 @@ public DatabaseFilterResult buildDatabaseQuery(Context context) { List args = new ArrayList(fields.size()); where.append("("); for (int i = 0; i < fields.size(); i++) { - where.append("EXISTS (SELECT tmp.* FROM metadatavalue tmp WHERE tmp.item_id=i.item_id AND tmp.metadata_field_id=?)"); + where.append("EXISTS (SELECT tmp.* FROM metadatavalue tmp WHERE tmp.resource_id=i.item_id AND tmp.resource_type_id=" + Constants.ITEM+ " AND tmp.metadata_field_id=?)"); args.add(fieldResolver.getFieldID(context, fields.get(i))); if (i < fields.size() - 1) diff --git a/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceSetSpecFilter.java b/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceSetSpecFilter.java index 141438472077..3c1d0d9b112c 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceSetSpecFilter.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceSetSpecFilter.java @@ -50,7 +50,7 @@ public DatabaseFilterResult buildDatabaseQuery(Context context) { DSpaceObject dso = handleResolver.resolve(setSpec.replace("col_", "")); return new DatabaseFilterResult( - "EXISTS (SELECT tmp.* FROM collection2item tmp WHERE tmp.item_id=i.item_id AND collection_id = ?)", + "EXISTS (SELECT tmp.* FROM collection2item tmp WHERE tmp.resource_id=i.item_id AND collection_id = ?)", dso.getID()); } catch (Exception ex) @@ -66,7 +66,7 @@ else if (setSpec.startsWith("com_")) List list = collectionsService.getAllSubCollections(dso.getID()); String subCollections = StringUtils.join(list.iterator(), ","); return new DatabaseFilterResult( - "EXISTS (SELECT tmp.* FROM collection2item tmp WHERE tmp.item_id=i.item_id AND collection_id IN (" + "EXISTS (SELECT tmp.* FROM collection2item tmp WHERE tmp.resource_id=i.item_id AND collection_id IN (" + subCollections + "))"); } catch (Exception e) @@ -116,4 +116,4 @@ else if (setSpec.startsWith("com_")) return new SolrFilterResult(); } -} \ No newline at end of file +} diff --git a/dspace-oai/src/test/java/org/dspace/xoai/tests/unit/services/impl/database/DSpaceDatabaseQueryResolverTest.java b/dspace-oai/src/test/java/org/dspace/xoai/tests/unit/services/impl/database/DSpaceDatabaseQueryResolverTest.java index 7d4e24985fe7..330092785464 100644 --- a/dspace-oai/src/test/java/org/dspace/xoai/tests/unit/services/impl/database/DSpaceDatabaseQueryResolverTest.java +++ b/dspace-oai/src/test/java/org/dspace/xoai/tests/unit/services/impl/database/DSpaceDatabaseQueryResolverTest.java @@ -17,6 +17,7 @@ import com.lyncode.xoai.dataprovider.xml.xoaiconfig.parameters.ParameterList; import com.lyncode.xoai.dataprovider.xml.xoaiconfig.parameters.ParameterMap; import com.lyncode.xoai.dataprovider.xml.xoaiconfig.parameters.StringValue; +import org.dspace.core.Constants; import org.dspace.xoai.filter.DSpaceMetadataExistsFilter; import org.dspace.xoai.filter.DSpaceSetSpecFilter; import org.dspace.xoai.filter.DateFromFilter; @@ -116,7 +117,7 @@ public void customConditionForMetadataExistsFilterWithOneSingleValue() throws Ex DatabaseQuery result = underTest.buildQuery(scopedFilters, START, LENGTH); - assertThat(result.getQuery(), is("SELECT i.* FROM item i WHERE i.in_archive=true AND ((EXISTS (SELECT tmp.* FROM metadatavalue tmp WHERE tmp.item_id=i.item_id AND tmp.metadata_field_id=?))) ORDER BY i.item_id OFFSET ? LIMIT ?")); + assertThat(result.getQuery(), is("SELECT i.* FROM item i WHERE i.in_archive=true AND ((EXISTS (SELECT tmp.* FROM metadatavalue tmp WHERE tmp.resource_id=i.item_id AND tmp.resource_type_id=" + Constants.ITEM + " AND tmp.metadata_field_id=?))) ORDER BY i.item_id OFFSET ? LIMIT ?")); assertThat(((Integer) result.getParameters().get(0)), is(1)); assertThat((Integer) result.getParameters().get(1), is(START)); assertThat((Integer) result.getParameters().get(2), is(LENGTH)); @@ -140,7 +141,7 @@ public void customConditionForMetadataExistsFilterWithMultipleValues() throws Ex DatabaseQuery result = underTest.buildQuery(scopedFilters, START, LENGTH); - assertThat(result.getQuery(), is("SELECT i.* FROM item i WHERE i.in_archive=true AND ((EXISTS (SELECT tmp.* FROM metadatavalue tmp WHERE tmp.item_id=i.item_id AND tmp.metadata_field_id=?) OR EXISTS (SELECT tmp.* FROM metadatavalue tmp WHERE tmp.item_id=i.item_id AND tmp.metadata_field_id=?))) ORDER BY i.item_id OFFSET ? LIMIT ?")); + assertThat(result.getQuery(), is("SELECT i.* FROM item i WHERE i.in_archive=true AND ((EXISTS (SELECT tmp.* FROM metadatavalue tmp WHERE tmp.resource_id=i.item_id AND tmp.resource_type_id=" + Constants.ITEM + " AND tmp.metadata_field_id=?) OR EXISTS (SELECT tmp.* FROM metadatavalue tmp WHERE tmp.resource_id=i.item_id AND tmp.resource_type_id=" + Constants.ITEM + " AND tmp.metadata_field_id=?))) ORDER BY i.item_id OFFSET ? LIMIT ?")); assertThat(((Integer) result.getParameters().get(0)), is(1)); assertThat(((Integer) result.getParameters().get(1)), is(2)); assertThat((Integer) result.getParameters().get(2), is(START)); diff --git a/dspace-sword/src/main/java/org/dspace/sword/ItemCollectionGenerator.java b/dspace-sword/src/main/java/org/dspace/sword/ItemCollectionGenerator.java index 1469455c2d7a..1c791ed75f01 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/ItemCollectionGenerator.java +++ b/dspace-sword/src/main/java/org/dspace/sword/ItemCollectionGenerator.java @@ -54,7 +54,7 @@ public Collection buildCollection(DSpaceObject dso) throws DSpaceSWORDException // the item title is the sword collection title, or "untitled" otherwise String title = "Untitled"; - DCValue[] dcv = item.getMetadata("dc.title"); + DCValue[] dcv = item.getMetadataByMetadataString("dc.title"); if (dcv.length > 0) { title = dcv[0].value; @@ -67,7 +67,7 @@ public Collection buildCollection(DSpaceObject dso) throws DSpaceSWORDException // abstract is the short description of the item, if it exists String dcAbstract = ""; - DCValue[] dcva = item.getMetadata("dc.description.abstract"); + DCValue[] dcva = item.getMetadataByMetadataString("dc.description.abstract"); if (dcva.length > 0) { dcAbstract = dcva[0].value; diff --git a/dspace-sword/src/main/java/org/dspace/sword/ItemEntryGenerator.java b/dspace-sword/src/main/java/org/dspace/sword/ItemEntryGenerator.java index 880aa6c0db0f..342a1908b9f7 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/ItemEntryGenerator.java +++ b/dspace-sword/src/main/java/org/dspace/sword/ItemEntryGenerator.java @@ -47,7 +47,7 @@ protected ItemEntryGenerator(SWORDService service) */ protected void addCategories() { - DCValue[] dcv = item.getMetadata("dc.subject.*"); + DCValue[] dcv = item.getMetadataByMetadataString("dc.subject.*"); if (dcv != null) { for (int i = 0; i < dcv.length; i++) @@ -233,7 +233,7 @@ protected void addLinks() */ protected void addPublishDate() { - DCValue[] dcv = item.getMetadata("dc.date.issued"); + DCValue[] dcv = item.getMetadataByMetadataString("dc.date.issued"); if (dcv != null && dcv.length == 1) { entry.setPublished(dcv[0].value); @@ -298,7 +298,7 @@ protected void addRights() */ protected void addSummary() { - DCValue[] dcv = item.getMetadata("dc.description.abstract"); + DCValue[] dcv = item.getMetadataByMetadataString("dc.description.abstract"); if (dcv != null) { for (int i = 0; i < dcv.length; i++) @@ -317,7 +317,7 @@ protected void addSummary() */ protected void addTitle() { - DCValue[] dcv = item.getMetadata("dc.title"); + DCValue[] dcv = item.getMetadataByMetadataString("dc.title"); if (dcv != null) { for (int i = 0; i < dcv.length; i++) @@ -337,7 +337,7 @@ protected void addTitle() protected void addLastUpdatedDate() { String config = ConfigurationManager.getProperty("sword-server", "updated.field"); - DCValue[] dcv = item.getMetadata(config); + DCValue[] dcv = item.getMetadataByMetadataString(config); if (dcv != null && dcv.length == 1) { DCDate dcd = new DCDate(dcv[0].value); diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/AtomStatementDisseminator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/AtomStatementDisseminator.java index 0b9f4909af08..b54b74e9c2a7 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/AtomStatementDisseminator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/AtomStatementDisseminator.java @@ -43,7 +43,7 @@ private String stringMetadata(Item item, String field) return null; } - DCValue[] dcvs = item.getMetadata(field); + DCValue[] dcvs = item.getMetadataByMetadataString(field); if (dcvs == null || dcvs.length == 0) { return null; diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java b/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java index de59da0563ff..ca0c53de732a 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java @@ -180,7 +180,7 @@ private String stringMetadata(Item item, String field) return null; } - DCValue[] dcvs = item.getMetadata(field); + DCValue[] dcvs = item.getMetadataByMetadataString(field); if (dcvs == null) { return null; diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/ReceiptGenerator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/ReceiptGenerator.java index 41b6e582f0fc..8a1226a4e711 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/ReceiptGenerator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/ReceiptGenerator.java @@ -222,7 +222,7 @@ protected DepositReceipt createReceipt(Context context, Item item, SwordConfigur */ protected void addCategories(DepositResult result, DepositReceipt receipt) { - DCValue[] dcv = result.getItem().getMetadata("dc.subject.*"); + DCValue[] dcv = result.getItem().getMetadataByMetadataString("dc.subject.*"); if (dcv != null) { for (int i = 0; i < dcv.length; i++) @@ -234,7 +234,7 @@ protected void addCategories(DepositResult result, DepositReceipt receipt) protected void addCategories(Item item, DepositReceipt receipt) { - DCValue[] dcv = item.getMetadata("dc.subject.*"); + DCValue[] dcv = item.getMetadataByMetadataString("dc.subject.*"); if (dcv != null) { for (int i = 0; i < dcv.length; i++) @@ -250,7 +250,7 @@ protected void addCategories(Item item, DepositReceipt receipt) */ protected void addPublishDate(DepositResult result, DepositReceipt receipt) { - DCValue[] dcv = result.getItem().getMetadata("dc.date.issued"); + DCValue[] dcv = result.getItem().getMetadataByMetadataString("dc.date.issued"); if (dcv != null && dcv.length == 1) { try @@ -269,7 +269,7 @@ protected void addPublishDate(DepositResult result, DepositReceipt receipt) protected void addPublishDate(Item item, DepositReceipt receipt) { - DCValue[] dcv = item.getMetadata("dc.date.issued"); + DCValue[] dcv = item.getMetadataByMetadataString("dc.date.issued"); if (dcv != null && dcv.length == 1) { try @@ -293,7 +293,7 @@ protected void addPublishDate(Item item, DepositReceipt receipt) protected void addLastUpdatedDate(DepositResult result, DepositReceipt receipt) { String config = ConfigurationManager.getProperty("swordv2-server", "updated.field"); - DCValue[] dcv = result.getItem().getMetadata(config); + DCValue[] dcv = result.getItem().getMetadataByMetadataString(config); if (dcv != null && dcv.length == 1) { try @@ -313,7 +313,7 @@ protected void addLastUpdatedDate(DepositResult result, DepositReceipt receipt) protected void addLastUpdatedDate(Item item, DepositReceipt receipt) { String config = ConfigurationManager.getProperty("swordv2-server", "updated.field"); - DCValue[] dcv = item.getMetadata(config); + DCValue[] dcv = item.getMetadataByMetadataString(config); if (dcv != null && dcv.length == 1) { try diff --git a/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/statisticsElasticSearch/CSVOutputter.java b/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/statisticsElasticSearch/CSVOutputter.java index 9a3e6398126e..554a7f290abb 100644 --- a/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/statisticsElasticSearch/CSVOutputter.java +++ b/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/statisticsElasticSearch/CSVOutputter.java @@ -26,7 +26,6 @@ import org.dspace.content.DSpaceObject; import org.dspace.content.Item; import org.dspace.core.Context; -import org.dspace.storage.rdbms.TableRow; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; @@ -189,9 +188,9 @@ private void addTermFacetToWriter(TermsFacet termsFacet, String termType) throws entryValues[2] = bitstream.getBundles()[0].getName(); entryValues[3] = item.getName(); entryValues[4] = "http://hdl.handle.net/" + item.getHandle(); - entryValues[5] = wrapInDelimitedString(item.getMetadata("dc.creator")); - entryValues[6] = wrapInDelimitedString(item.getMetadata("dc.publisher")); - entryValues[7] = wrapInDelimitedString(item.getMetadata("dc.date.issued")); + entryValues[5] = wrapInDelimitedString(item.getMetadataByMetadataString("dc.creator")); + entryValues[6] = wrapInDelimitedString(item.getMetadataByMetadataString("dc.publisher")); + entryValues[7] = wrapInDelimitedString(item.getMetadataByMetadataString("dc.date.issued")); entryValues[8] = facetEntry.getCount() + ""; writer.writeNext(entryValues); } else { diff --git a/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/statisticsElasticSearch/ElasticSearchStatsViewer.java b/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/statisticsElasticSearch/ElasticSearchStatsViewer.java index 05304c89a165..5604a00aab97 100644 --- a/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/statisticsElasticSearch/ElasticSearchStatsViewer.java +++ b/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/statisticsElasticSearch/ElasticSearchStatsViewer.java @@ -409,7 +409,7 @@ private String getOwningText(DSpaceObject dso) { } private String getFirstMetadataValue(Item item, String metadataKey) { - DCValue[] dcValue = item.getMetadata(metadataKey); + DCValue[] dcValue = item.getMetadataByMetadataString(metadataKey); if(dcValue.length > 0) { return dcValue[0].value; } else { diff --git a/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/submission/submit/DescribeStep.java b/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/submission/submit/DescribeStep.java index e530dfd68f78..aa1f600d50cd 100644 --- a/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/submission/submit/DescribeStep.java +++ b/dspace-xmlui/src/main/java/org/dspace/app/xmlui/aspect/submission/submit/DescribeStep.java @@ -181,9 +181,9 @@ public void addBody(Body body) throws SAXException, WingException, // Fetch the document type (dc.type) String documentType = ""; - if( (item.getMetadata("dc.type") != null) && (item.getMetadata("dc.type").length >0) ) + if( (item.getMetadataByMetadataString("dc.type") != null) && (item.getMetadataByMetadataString("dc.type").length >0) ) { - documentType = item.getMetadata("dc.type")[0].value; + documentType = item.getMetadataByMetadataString("dc.type")[0].value; } // Iterate over all inputs and add it to the form. diff --git a/dspace-xmlui/src/main/java/org/dspace/springmvc/BibTexView.java b/dspace-xmlui/src/main/java/org/dspace/springmvc/BibTexView.java index 9fca7fa1d417..105c87092e49 100644 --- a/dspace-xmlui/src/main/java/org/dspace/springmvc/BibTexView.java +++ b/dspace-xmlui/src/main/java/org/dspace/springmvc/BibTexView.java @@ -25,8 +25,6 @@ import java.util.List; import java.util.Map; import java.util.StringTokenizer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * @author Fabio Bolognesi (fabio at atmire dot com) @@ -133,7 +131,7 @@ else if (index + 1 < authors.length) { // not last one private String getMetadataValue(Item item, String metadatafield) { - for (DCValue value : item.getMetadata(metadatafield)) + for (DCValue value : item.getMetadataByMetadataString(metadatafield)) { return value.value; } @@ -145,16 +143,16 @@ private String[] getAuthors(Item aItem) { ArrayList authors = new ArrayList(); - authors.addAll(getAuthors(aItem.getMetadata("dc.contributor.author"))); - authors.addAll(getAuthors(aItem.getMetadata("dc.creator"))); - authors.addAll(getAuthors(aItem.getMetadata("dc.contributor"))); + authors.addAll(getAuthors(aItem.getMetadataByMetadataString("dc.contributor.author"))); + authors.addAll(getAuthors(aItem.getMetadataByMetadataString("dc.creator"))); + authors.addAll(getAuthors(aItem.getMetadataByMetadataString("dc.contributor"))); return authors.toArray(new String[authors.size()]); } private String getYear(Item aItem) { - for (DCValue date : aItem.getMetadata("dc.date.issued")) + for (DCValue date : aItem.getMetadataByMetadataString("dc.date.issued")) { return date.value.substring(0, 4); } diff --git a/dspace-xmlui/src/main/java/org/dspace/springmvc/RisView.java b/dspace-xmlui/src/main/java/org/dspace/springmvc/RisView.java index 291dce863ef6..7e5c3e31339e 100644 --- a/dspace-xmlui/src/main/java/org/dspace/springmvc/RisView.java +++ b/dspace-xmlui/src/main/java/org/dspace/springmvc/RisView.java @@ -13,8 +13,6 @@ import org.dspace.content.DSpaceObject; import org.dspace.content.Item; import org.dspace.core.Context; -import org.dspace.identifier.IdentifierService; -import org.dspace.utils.DSpace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.servlet.View; @@ -28,8 +26,6 @@ import java.util.List; import java.util.Map; import java.util.StringTokenizer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * @author Fabio Bolognesi (fabio at atmire dot com) @@ -159,9 +155,9 @@ private String[] getAuthors(Item aItem) { ArrayList authors = new ArrayList(); - authors.addAll(getAuthors(aItem.getMetadata("dc.contributor.author"))); - authors.addAll(getAuthors(aItem.getMetadata("dc.creator"))); - authors.addAll(getAuthors(aItem.getMetadata("dc.contributor"))); + authors.addAll(getAuthors(aItem.getMetadataByMetadataString("dc.contributor.author"))); + authors.addAll(getAuthors(aItem.getMetadataByMetadataString("dc.creator"))); + authors.addAll(getAuthors(aItem.getMetadataByMetadataString("dc.contributor"))); return authors.toArray(new String[authors.size()]); } @@ -170,7 +166,7 @@ private String[] getKeywords(Item aItem) { ArrayList keywordList = new ArrayList(); - for (DCValue keyword : aItem.getMetadata("dc.subject")) + for (DCValue keyword : aItem.getMetadataByMetadataString("dc.subject")) { if (keyword.value.length() < 255) { @@ -178,7 +174,7 @@ private String[] getKeywords(Item aItem) } } - for (DCValue keyword : aItem.getMetadata("dwc.ScientificName")) + for (DCValue keyword : aItem.getMetadataByMetadataString("dwc.ScientificName")) { if (keyword.value.length() < 255) { @@ -193,7 +189,7 @@ private String[] getDate(Item item) { StringTokenizer tokenizer; - for (DCValue date : item.getMetadata("dc.date.issued")) + for (DCValue date : item.getMetadataByMetadataString("dc.date.issued")) { tokenizer = new StringTokenizer(date.value, "-/ T"); String[] dateParts = new String[tokenizer.countTokens()]; @@ -211,7 +207,7 @@ private String[] getDate(Item item) private String getMetadataValue(Item item, String metadatafield) { - for (DCValue value : item.getMetadata(metadatafield)) + for (DCValue value : item.getMetadataByMetadataString(metadatafield)) { return value.value; } diff --git a/dspace/config/registries/dublin-core-types.xml b/dspace/config/registries/dublin-core-types.xml index fa449f5eb16a..b324267b8206 100644 --- a/dspace/config/registries/dublin-core-types.xml +++ b/dspace/config/registries/dublin-core-types.xml @@ -584,4 +584,18 @@ Nature or genre of content. + + + dc + provenance + + + + + + dc + rights + license + + diff --git a/dspace/config/registries/eperson-types.xml b/dspace/config/registries/eperson-types.xml new file mode 100644 index 000000000000..a2756675f92d --- /dev/null +++ b/dspace/config/registries/eperson-types.xml @@ -0,0 +1,47 @@ + + + + DSpace EPerson + Kevin Van de Velde + Bert Vanderhallen + Ben Bosman + Mark Diggory + + + + eperson + http://dspace.org/eperson + + + + + eperson + firstname + Metadata field used for the first name + + + + eperson + lastname + Metadata field used for the last name + + + + eperson + phone + Metadata field used for the phone number + + + + eperson + netid + Metadata field used for the net id + + + + eperson + language + Metadata field used for the language + + + diff --git a/dspace/etc/oracle/database_schema.sql b/dspace/etc/oracle/database_schema.sql index 8c22bddd51b4..e4f2c19ed799 100644 --- a/dspace/etc/oracle/database_schema.sql +++ b/dspace/etc/oracle/database_schema.sql @@ -109,13 +109,9 @@ CREATE TABLE Bitstream ( bitstream_id INTEGER PRIMARY KEY, bitstream_format_id INTEGER REFERENCES BitstreamFormatRegistry(bitstream_format_id), - name VARCHAR2(256), size_bytes INTEGER, checksum VARCHAR2(64), checksum_algorithm VARCHAR2(32), - description VARCHAR2(2000), - user_format_description VARCHAR2(2000), - source VARCHAR2(256), internal_id VARCHAR2(256), deleted NUMBER(1), store_number INTEGER, @@ -134,16 +130,11 @@ CREATE TABLE EPerson password VARCHAR2(128), salt VARCHAR2(32), digest_algorithm VARCHAR2(16), - firstname VARCHAR2(64), - lastname VARCHAR2(64), can_log_in NUMBER(1), require_certificate NUMBER(1), self_registered NUMBER(1), last_active TIMESTAMP, - sub_frequency INTEGER, - phone VARCHAR2(32), - netid VARCHAR2(64) UNIQUE, - language VARCHAR2(64) + sub_frequency INTEGER ); ------------------------------------------------------- @@ -151,8 +142,7 @@ CREATE TABLE EPerson ------------------------------------------------------- CREATE TABLE EPersonGroup ( - eperson_group_id INTEGER PRIMARY KEY, - name VARCHAR2(256) UNIQUE + eperson_group_id INTEGER PRIMARY KEY ); ------------------------------------------------------ @@ -269,7 +259,8 @@ CREATE TABLE MetadataFieldRegistry CREATE TABLE MetadataValue ( metadata_value_id INTEGER PRIMARY KEY, - item_id INTEGER REFERENCES Item(item_id), + resource_id INTEGER NOT NULL, + resource_type_id INTEGER NOT NULL, metadata_field_id INTEGER REFERENCES MetadataFieldRegistry(metadata_field_id), text_value CLOB, text_lang VARCHAR(24), @@ -283,18 +274,16 @@ INSERT INTO MetadataSchemaRegistry VALUES (1,'http://dublincore.org/documents/dc -- Create a dcvalue view for backwards compatibilty CREATE VIEW dcvalue AS - SELECT MetadataValue.metadata_value_id AS "dc_value_id", MetadataValue.item_id, + SELECT MetadataValue.metadata_value_id AS "dc_value_id", MetadataValue.resource_id, MetadataValue.metadata_field_id AS "dc_type_id", MetadataValue.text_value, MetadataValue.text_lang, MetadataValue.place FROM MetadataValue, MetadataFieldRegistry WHERE MetadataValue.metadata_field_id = MetadataFieldRegistry.metadata_field_id - AND MetadataFieldRegistry.metadata_schema_id = 1; + AND MetadataFieldRegistry.metadata_schema_id = 1 AND MetadataValue.resource_type_id = 2; -- An index for item_id - almost all access is based on -- instantiating the item object, which grabs all values -- related to that item -CREATE INDEX metadatavalue_item_idx ON MetadataValue(item_id); -CREATE INDEX metadatavalue_item_idx2 ON MetadataValue(item_id,metadata_field_id); CREATE INDEX metadatavalue_field_fk_idx ON MetadataValue(metadata_field_id); CREATE INDEX metadatafield_schema_idx ON MetadataFieldRegistry(metadata_schema_id); @@ -304,12 +293,7 @@ CREATE INDEX metadatafield_schema_idx ON MetadataFieldRegistry(metadata_schema_i CREATE TABLE Community ( community_id INTEGER PRIMARY KEY, - name VARCHAR2(128), - short_description VARCHAR2(512), - introductory_text CLOB, logo_bitstream_id INTEGER REFERENCES Bitstream(bitstream_id), - copyright_text CLOB, - side_bar_text VARCHAR2(2000), admin INTEGER REFERENCES EPersonGroup( eperson_group_id ) ); @@ -322,15 +306,8 @@ CREATE INDEX community_admin_fk_idx ON Community(admin); CREATE TABLE Collection ( collection_id INTEGER PRIMARY KEY, - name VARCHAR2(128), - short_description VARCHAR2(512), - introductory_text CLOB, logo_bitstream_id INTEGER REFERENCES Bitstream(bitstream_id), template_item_id INTEGER REFERENCES Item(item_id), - provenance_description VARCHAR2(2000), - license CLOB, - copyright_text CLOB, - side_bar_text VARCHAR2(2000), workflow_step_1 INTEGER REFERENCES EPersonGroup( eperson_group_id ), workflow_step_2 INTEGER REFERENCES EPersonGroup( eperson_group_id ), workflow_step_3 INTEGER REFERENCES EPersonGroup( eperson_group_id ), @@ -600,8 +577,8 @@ CREATE TABLE community_item_count ( -- and administrators ------------------------------------------------------- -- We don't use getnextid() for 'anonymous' since the sequences start at '1' -INSERT INTO epersongroup VALUES(0, 'Anonymous'); -INSERT INTO epersongroup VALUES(1, 'Administrator'); +INSERT INTO epersongroup VALUES(0); +INSERT INTO epersongroup VALUES(1); ------------------------------------------------------- diff --git a/dspace/etc/oracle/database_schema_4-5.sql b/dspace/etc/oracle/database_schema_4-5.sql index 9531ccc3912f..3145e2226e5c 100644 --- a/dspace/etc/oracle/database_schema_4-5.sql +++ b/dspace/etc/oracle/database_schema_4-5.sql @@ -12,3 +12,349 @@ ------------------------------------------------------ ALTER TABLE requestitem ADD request_message VARCHAR2(2000); + +DECLARE +statement VARCHAR2(2000); +constr_name VARCHAR2(300); +BEGIN + SELECT CONSTRAINT_NAME INTO constr_name + FROM USER_CONS_COLUMNS + WHERE table_name = 'METADATAVALUE' AND COLUMN_NAME='ITEM_ID'; + statement := 'ALTER TABLE METADATAVALUE DROP CONSTRAINT '|| constr_name; + EXECUTE IMMEDIATE(statement); +END; +/ + +alter table metadatavalue rename column item_id to resource_id; + +alter table metadatavalue MODIFY(resource_id not null); +alter table metadatavalue add resource_type_id integer; +UPDATE metadatavalue SET resource_type_id = 2; +alter table metadatavalue MODIFY(resource_type_id not null); + + + +-- --------- +-- community +-- --------- + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +community_id AS resource_id, +4 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'description' and qualifier is null) AS metadata_field_id, +introductory_text AS text_value, +null AS text_lang, +0 AS place +FROM community where not introductory_text is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +community_id AS resource_id, +4 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'description' and qualifier = 'abstract') AS metadata_field_id, +short_description AS text_value, +null AS text_lang, +0 AS place +FROM community where not short_description is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +community_id AS resource_id, +4 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'description' and qualifier = 'tableofcontents') AS metadata_field_id, +side_bar_text AS text_value, +null AS text_lang, +0 AS place +FROM community where not side_bar_text is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +community_id AS resource_id, +4 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'rights' and qualifier is null) AS metadata_field_id, +copyright_text AS text_value, +null AS text_lang, +0 AS place +FROM community where not copyright_text is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +community_id AS resource_id, +4 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'title' and qualifier is null) AS metadata_field_id, +name AS text_value, +null AS text_lang, +0 AS place +FROM community where not name is null; + +alter table community drop (introductory_text, short_description, side_bar_text, copyright_text, name); + + +-- ---------- +-- collection +-- ---------- + + + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +collection_id AS resource_id, +3 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'description' and qualifier is null) AS metadata_field_id, +introductory_text AS text_value, +null AS text_lang, +0 AS place +FROM collection where not introductory_text is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +collection_id AS resource_id, +3 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'description' and qualifier = 'abstract') AS metadata_field_id, +short_description AS text_value, +null AS text_lang, +0 AS place +FROM collection where not short_description is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +collection_id AS resource_id, +3 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'description' and qualifier = 'tableofcontents') AS metadata_field_id, +side_bar_text AS text_value, +null AS text_lang, +0 AS place +FROM collection where not side_bar_text is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +collection_id AS resource_id, +3 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'rights' and qualifier is null) AS metadata_field_id, +copyright_text AS text_value, +null AS text_lang, +0 AS place +FROM collection where not copyright_text is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +collection_id AS resource_id, +3 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'title' and qualifier is null) AS metadata_field_id, +name AS text_value, +null AS text_lang, +0 AS place +FROM collection where not name is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +collection_id AS resource_id, +3 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'provenance' and qualifier is null) AS metadata_field_id, +provenance_description AS text_value, +null AS text_lang, +0 AS place +FROM collection where not provenance_description is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +collection_id AS resource_id, +3 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'rights' and qualifier = 'license') AS metadata_field_id, +license AS text_value, +null AS text_lang, +0 AS place +FROM collection where not license is null; + +alter table collection drop (introductory_text, short_description, copyright_text, side_bar_text, name, license, provenance_description); + + +-- --------- +-- bundle +-- --------- + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +bundle_id AS resource_id, +1 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'title' and qualifier is null) AS metadata_field_id, +name AS text_value, +null AS text_lang, +0 AS place +FROM bundle where not name is null; + +alter table bundle drop column name; + + + +-- --------- +-- bitstream +-- --------- + + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +bitstream_id AS resource_id, +0 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'title' and qualifier is null) AS metadata_field_id, +name AS text_value, +null AS text_lang, +0 AS place +FROM bitstream where not name is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +bitstream_id AS resource_id, +0 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'description' and qualifier is null) AS metadata_field_id, +description AS text_value, +null AS text_lang, +0 AS place +FROM bitstream where not description is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +bitstream_id AS resource_id, +0 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'format' and qualifier is null) AS metadata_field_id, +user_format_description AS text_value, +null AS text_lang, +0 AS place +FROM bitstream where not user_format_description is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +bitstream_id AS resource_id, +0 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'source' and qualifier is null) AS metadata_field_id, +source AS text_value, +null AS text_lang, +0 AS place +FROM bitstream where not source is null; + +alter table bitstream drop (name, description, user_format_description, source); + + +-- --------- +-- epersongroup +-- --------- + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +eperson_group_id AS resource_id, +6 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'title' and qualifier is null) AS metadata_field_id, +name AS text_value, +null AS text_lang, +0 AS place +FROM epersongroup where not name is null; + +alter table epersongroup drop column name; + + + +-- --------- +-- eperson +-- --------- + + + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +eperson_id AS resource_id, +7 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='eperson') and element = 'email' and qualifier is null) AS metadata_field_id, +email AS text_value, +null AS text_lang, +0 AS place +FROM eperson where not email is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +eperson_id AS resource_id, +7 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='eperson') and element = 'firstname' and qualifier is null) AS metadata_field_id, +firstname AS text_value, +null AS text_lang, +0 AS place +FROM eperson where not firstname is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +eperson_id AS resource_id, +7 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='eperson') and element = 'lastname' and qualifier is null) AS metadata_field_id, +lastname AS text_value, +null AS text_lang, +0 AS place +FROM eperson where not lastname is null; + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +eperson_id AS resource_id, +7 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='eperson') and element = 'phone' and qualifier is null) AS metadata_field_id, +phone AS text_value, +null AS text_lang, +0 AS place +FROM eperson where not phone is null; + + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +eperson_id AS resource_id, +7 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='eperson') and element = 'netid' and qualifier is null) AS metadata_field_id, +netid AS text_value, +null AS text_lang, +0 AS place +FROM eperson where not netid is null; + + +INSERT INTO metadatavalue (metadata_value_id, resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +metadatavalue_seq.nextval as metadata_value_id, +eperson_id AS resource_id, +7 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='eperson') and element = 'language' and qualifier is null) AS metadata_field_id, +language AS text_value, +null AS text_lang, +0 AS place +FROM eperson where not language is null; + + +alter table eperson drop (firstname, lastname, phone, netid, language); + +drop view dcvalue; + +CREATE VIEW dcvalue AS + SELECT MetadataValue.metadata_value_id AS "dc_value_id", MetadataValue.resource_id, + MetadataValue.metadata_field_id AS "dc_type_id", MetadataValue.text_value, + MetadataValue.text_lang, MetadataValue.place + FROM MetadataValue, MetadataFieldRegistry + WHERE MetadataValue.metadata_field_id = MetadataFieldRegistry.metadata_field_id + AND MetadataFieldRegistry.metadata_schema_id = 1 AND MetadataValue.resource_type_id = 2; diff --git a/dspace/etc/postgres/database_schema.sql b/dspace/etc/postgres/database_schema.sql index 4e1d46a93a52..fb988de922ff 100644 --- a/dspace/etc/postgres/database_schema.sql +++ b/dspace/etc/postgres/database_schema.sql @@ -146,13 +146,9 @@ CREATE TABLE Bitstream ( bitstream_id INTEGER PRIMARY KEY, bitstream_format_id INTEGER REFERENCES BitstreamFormatRegistry(bitstream_format_id), - name VARCHAR(256), size_bytes BIGINT, checksum VARCHAR(64), checksum_algorithm VARCHAR(32), - description TEXT, - user_format_description TEXT, - source VARCHAR(256), internal_id VARCHAR(256), deleted BOOL, store_number INTEGER, @@ -171,31 +167,25 @@ CREATE TABLE EPerson password VARCHAR(128), salt VARCHAR(32), digest_algorithm VARCHAR(16), - firstname VARCHAR(64), - lastname VARCHAR(64), can_log_in BOOL, require_certificate BOOL, self_registered BOOL, last_active TIMESTAMP, - sub_frequency INTEGER, - phone VARCHAR(32), - netid VARCHAR(64), - language VARCHAR(64) + sub_frequency INTEGER ); -- index by email CREATE INDEX eperson_email_idx ON EPerson(email); -- index by netid -CREATE INDEX eperson_netid_idx ON EPerson(netid); +--CREATE INDEX eperson_netid_idx ON EPerson(netid); ------------------------------------------------------- -- EPersonGroup table ------------------------------------------------------- CREATE TABLE EPersonGroup ( - eperson_group_id INTEGER PRIMARY KEY, - name VARCHAR(256) UNIQUE + eperson_group_id INTEGER PRIMARY KEY ); ------------------------------------------------------ @@ -312,7 +302,8 @@ CREATE TABLE MetadataFieldRegistry CREATE TABLE MetadataValue ( metadata_value_id INTEGER PRIMARY KEY DEFAULT NEXTVAL('metadatavalue_seq'), - item_id INTEGER REFERENCES Item(item_id), + resource_id INTEGER NOT NULL, + resource_type_id INTEGER NOT NULL, metadata_field_id INTEGER REFERENCES MetadataFieldRegistry(metadata_field_id), text_value TEXT, text_lang VARCHAR(24), @@ -323,18 +314,16 @@ CREATE TABLE MetadataValue -- Create a dcvalue view for backwards compatibilty CREATE VIEW dcvalue AS - SELECT MetadataValue.metadata_value_id AS "dc_value_id", MetadataValue.item_id, + SELECT MetadataValue.metadata_value_id AS "dc_value_id", MetadataValue.resource_id, MetadataValue.metadata_field_id AS "dc_type_id", MetadataValue.text_value, MetadataValue.text_lang, MetadataValue.place FROM MetadataValue, MetadataFieldRegistry WHERE MetadataValue.metadata_field_id = MetadataFieldRegistry.metadata_field_id - AND MetadataFieldRegistry.metadata_schema_id = 1; + AND MetadataFieldRegistry.metadata_schema_id = 1 AND MetadataValue.resource_type_id = 2; -- An index for item_id - almost all access is based on -- instantiating the item object, which grabs all values -- related to that item -CREATE INDEX metadatavalue_item_idx ON MetadataValue(item_id); -CREATE INDEX metadatavalue_item_idx2 ON MetadataValue(item_id,metadata_field_id); CREATE INDEX metadatavalue_field_fk_idx ON MetadataValue(metadata_field_id); CREATE INDEX metadatafield_schema_idx ON MetadataFieldRegistry(metadata_schema_id); @@ -344,12 +333,7 @@ CREATE INDEX metadatafield_schema_idx ON MetadataFieldRegistry(metadata_schema_i CREATE TABLE Community ( community_id INTEGER PRIMARY KEY, - name VARCHAR(128), - short_description VARCHAR(512), - introductory_text TEXT, logo_bitstream_id INTEGER REFERENCES Bitstream(bitstream_id), - copyright_text TEXT, - side_bar_text TEXT, admin INTEGER REFERENCES EPersonGroup( eperson_group_id ) ); @@ -362,15 +346,8 @@ CREATE INDEX community_admin_fk_idx ON Community(admin); CREATE TABLE Collection ( collection_id INTEGER PRIMARY KEY, - name VARCHAR(128), - short_description VARCHAR(512), - introductory_text TEXT, logo_bitstream_id INTEGER REFERENCES Bitstream(bitstream_id), template_item_id INTEGER REFERENCES Item(item_id), - provenance_description TEXT, - license TEXT, - copyright_text TEXT, - side_bar_text TEXT, workflow_step_1 INTEGER REFERENCES EPersonGroup( eperson_group_id ), workflow_step_2 INTEGER REFERENCES EPersonGroup( eperson_group_id ), workflow_step_3 INTEGER REFERENCES EPersonGroup( eperson_group_id ), @@ -645,8 +622,9 @@ CREATE TABLE community_item_count ( -- and administrators ------------------------------------------------------- -- We don't use getnextid() for 'anonymous' since the sequences start at '1' -INSERT INTO epersongroup VALUES(0, 'Anonymous'); -INSERT INTO epersongroup VALUES(getnextid('epersongroup'), 'Administrator'); +INSERT INTO epersongroup VALUES(0); +INSERT INTO epersongroup VALUES(getnextid('epersongroup')); + ------------------------------------------------------- diff --git a/dspace/etc/postgres/database_schema_4_5.sql b/dspace/etc/postgres/database_schema_4_5.sql index 3bc6e789afd8..063edf42a8c6 100644 --- a/dspace/etc/postgres/database_schema_4_5.sql +++ b/dspace/etc/postgres/database_schema_4_5.sql @@ -14,4 +14,317 @@ BEGIN; ALTER TABLE requestitem ADD request_message TEXT; +alter table metadatavalue rename item_id to resource_id; +alter table metadatavalue alter column resource_id set not null; +alter table metadatavalue add column resource_type_id integer; +UPDATE metadatavalue SET resource_type_id = 2; +alter table metadatavalue alter column resource_type_id set not null; +alter table metadatavalue drop constraint metadatavalue_item_id_fkey; + + +-- --------- +-- community +-- --------- + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +community_id AS resource_id, +4 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'description' and qualifier is null) AS metadata_field_id, +introductory_text AS text_value, +null AS text_lang, +0 AS place +FROM community where not introductory_text is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +community_id AS resource_id, +4 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'description' and qualifier = 'abstract') AS metadata_field_id, +short_description AS text_value, +null AS text_lang, +0 AS place +FROM community where not short_description is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +community_id AS resource_id, +4 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'description' and qualifier = 'tableofcontents') AS metadata_field_id, +side_bar_text AS text_value, +null AS text_lang, +0 AS place +FROM community where not side_bar_text is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +community_id AS resource_id, +4 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'rights' and qualifier is null) AS metadata_field_id, +copyright_text AS text_value, +null AS text_lang, +0 AS place +FROM community where not copyright_text is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +community_id AS resource_id, +4 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'title' and qualifier is null) AS metadata_field_id, +name AS text_value, +null AS text_lang, +0 AS place +FROM community where not name is null; + +alter table community drop column introductory_text, drop column short_description, drop column side_bar_text, drop column copyright_text, drop column name; + + +-- ---------- +-- collection +-- ---------- + + + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +collection_id AS resource_id, +3 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'description' and qualifier is null) AS metadata_field_id, +introductory_text AS text_value, +null AS text_lang, +0 AS place +FROM collection where not introductory_text is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +collection_id AS resource_id, +3 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'description' and qualifier = 'abstract') AS metadata_field_id, +short_description AS text_value, +null AS text_lang, +0 AS place +FROM collection where not short_description is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +collection_id AS resource_id, +3 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'description' and qualifier = 'tableofcontents') AS metadata_field_id, +side_bar_text AS text_value, +null AS text_lang, +0 AS place +FROM collection where not side_bar_text is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +collection_id AS resource_id, +3 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'rights' and qualifier is null) AS metadata_field_id, +copyright_text AS text_value, +null AS text_lang, +0 AS place +FROM collection where not copyright_text is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +collection_id AS resource_id, +3 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'title' and qualifier is null) AS metadata_field_id, +name AS text_value, +null AS text_lang, +0 AS place +FROM collection where not name is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +collection_id AS resource_id, +3 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'provenance' and qualifier is null) AS metadata_field_id, +provenance_description AS text_value, +null AS text_lang, +0 AS place +FROM collection where not provenance_description is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +collection_id AS resource_id, +3 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'rights' and qualifier = 'license') AS metadata_field_id, +license AS text_value, +null AS text_lang, +0 AS place +FROM collection where not license is null; + +alter table collection drop column introductory_text, drop column short_description, drop column copyright_text, drop column side_bar_text, drop column name, drop column license, drop column provenance_description; + + +-- --------- +-- bundle +-- --------- + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +bundle_id AS resource_id, +1 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'title' and qualifier is null) AS metadata_field_id, +name AS text_value, +null AS text_lang, +0 AS place +FROM bundle where not name is null; + +alter table bundle drop column name; + + + +-- --------- +-- bitstream +-- --------- + + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +bitstream_id AS resource_id, +0 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'title' and qualifier is null) AS metadata_field_id, +name AS text_value, +null AS text_lang, +0 AS place +FROM bitstream where not name is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +bitstream_id AS resource_id, +0 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'description' and qualifier is null) AS metadata_field_id, +description AS text_value, +null AS text_lang, +0 AS place +FROM bitstream where not description is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +bitstream_id AS resource_id, +0 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'format' and qualifier is null) AS metadata_field_id, +user_format_description AS text_value, +null AS text_lang, +0 AS place +FROM bitstream where not user_format_description is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +bitstream_id AS resource_id, +0 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'source' and qualifier is null) AS metadata_field_id, +source AS text_value, +null AS text_lang, +0 AS place +FROM bitstream where not source is null; + +alter table bitstream drop column name, drop column description, drop column user_format_description, drop column source; + + +-- --------- +-- epersongroup +-- --------- + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +eperson_group_id AS resource_id, +6 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='dc') and element = 'title' and qualifier is null) AS metadata_field_id, +name AS text_value, +null AS text_lang, +0 AS place +FROM epersongroup where not name is null; + +alter table epersongroup drop column name; + + + +-- --------- +-- eperson +-- --------- + + + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +eperson_id AS resource_id, +7 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='eperson') and element = 'email' and qualifier is null) AS metadata_field_id, +email AS text_value, +null AS text_lang, +0 AS place +FROM eperson where not email is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +eperson_id AS resource_id, +7 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='eperson') and element = 'firstname' and qualifier is null) AS metadata_field_id, +firstname AS text_value, +null AS text_lang, +0 AS place +FROM eperson where not firstname is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +eperson_id AS resource_id, +7 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='eperson') and element = 'lastname' and qualifier is null) AS metadata_field_id, +lastname AS text_value, +null AS text_lang, +0 AS place +FROM eperson where not lastname is null; + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +eperson_id AS resource_id, +7 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='eperson') and element = 'phone' and qualifier is null) AS metadata_field_id, +phone AS text_value, +null AS text_lang, +0 AS place +FROM eperson where not phone is null; + + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +eperson_id AS resource_id, +7 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='eperson') and element = 'netid' and qualifier is null) AS metadata_field_id, +netid AS text_value, +null AS text_lang, +0 AS place +FROM eperson where not netid is null; + + +INSERT INTO metadatavalue (resource_id, resource_type_id, metadata_field_id, text_value, text_lang, place) +SELECT +eperson_id AS resource_id, +7 AS resource_type_id, +(select metadata_field_id from metadatafieldregistry where metadata_schema_id=(select metadata_schema_id from metadataschemaregistry where short_id='eperson') and element = 'language' and qualifier is null) AS metadata_field_id, +language AS text_value, +null AS text_lang, +0 AS place +FROM eperson where not language is null; + + +alter table eperson drop column firstname, drop column lastname, drop column phone, drop column netid, drop column language; + +-- --------- +-- dcvalue view +-- --------- + +drop view dcvalue; + +CREATE VIEW dcvalue AS + SELECT MetadataValue.metadata_value_id AS "dc_value_id", MetadataValue.resource_id, + MetadataValue.metadata_field_id AS "dc_type_id", MetadataValue.text_value, + MetadataValue.text_lang, MetadataValue.place + FROM MetadataValue, MetadataFieldRegistry + WHERE MetadataValue.metadata_field_id = MetadataFieldRegistry.metadata_field_id + AND MetadataFieldRegistry.metadata_schema_id = 1 AND MetadataValue.resource_type_id = 2; + COMMIT; \ No newline at end of file diff --git a/dspace/src/main/config/build.xml b/dspace/src/main/config/build.xml index c1cf5927062b..2bebe3877348 100644 --- a/dspace/src/main/config/build.xml +++ b/dspace/src/main/config/build.xml @@ -185,7 +185,7 @@ Common usage: - + @@ -879,6 +879,14 @@ Common usage: + + + + + + + + @@ -891,6 +899,52 @@ Common usage: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -958,6 +1012,14 @@ Common usage: + + + + + + + +