Mercurial > hg > LGDataverses
view src/main/java/edu/harvard/iq/dataverse/DatasetVersionServiceBean.java @ 14:be7787c36e58 default tip
new: nofity LGSercies for deleted files
| author | Zoe Hong <zhong@mpiwg-berlin.mpg.de> |
|---|---|
| date | Mon, 02 Nov 2015 16:41:23 +0100 |
| parents | a50cf11e5178 |
| children |
line wrap: on
line source
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package edu.harvard.iq.dataverse; import edu.harvard.iq.dataverse.DatasetVersion.VersionState; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.ejb.EJB; import javax.ejb.EJBException; import javax.ejb.Stateless; import javax.inject.Named; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.persistence.TypedQuery; /** * * @author skraffmiller */ @Stateless @Named public class DatasetVersionServiceBean implements java.io.Serializable { private static final Logger logger = Logger.getLogger(DatasetVersionServiceBean.class.getCanonicalName()); @EJB DatasetServiceBean datasetService; @EJB SettingsServiceBean settingsService; @PersistenceContext(unitName = "VDCNet-ejbPU") private EntityManager em; /** * Response to a successful request from the DatasetPage * * Used to help display messages in the cases when: * (1) A specific dataset version (including a DRAFT) is requested * (2) A different dataset is returned b/c the first one doesn't exist * * Simple example: "DRAFT" requested but no longer exists b/c it * was published and is now version "1.0" */ public class RetrieveDatasetVersionResponse{ private DatasetVersion datasetVersionForResponse; private boolean wasSpecificVersionRequested = false; private boolean didSpecificVersionMatch = false; private String actualVersion = null; private String requestedVersion = null; public RetrieveDatasetVersionResponse(DatasetVersion datasetVersion, String requestedVersion){ if (datasetVersion == null){ throw new IllegalArgumentException("datasetVersion cannot be null"); } //logger.fine("RetrieveDatasetVersionResponse: datasetVersion: " + datasetVersion.getSemanticVersion() + " requestedVersion: " + requestedVersion); //logger.fine("chosenVersion id: " + datasetVersion.getId() + " getFriendlyVersionNumber: " + datasetVersion.getFriendlyVersionNumber()); this.datasetVersionForResponse = datasetVersion; this.actualVersion = datasetVersion.getSemanticVersion(); this.requestedVersion = requestedVersion; this.checkVersion(); } public String getDifferentVersionMessage(){ if (this.wasSpecificVersionRequested && !this.didSpecificVersionMatch){ String userMsg; if (DatasetVersionServiceBean.this.isVersionAskingForDraft(this.requestedVersion)){ userMsg = "The \"DRAFT\" version was not found."; }else{ userMsg = "Version \"" + this.requestedVersion + "\" was not found."; } if (DatasetVersionServiceBean.this.isVersionAskingForDraft(this.actualVersion)){ userMsg += " This is the \"DRAFT\" version."; }else{ userMsg += " This is version \"" + this.actualVersion + "\"."; } return userMsg; } return null; } private void checkVersion(){ if (actualVersion==null){ // this shouldn't happen return; } //logger.fine("check version. requested: " + this.requestedVersion + " returned: " + actualVersion); // This may often be the case if version is not specified // if (requestedVersion == null || requestedVersion.equals("")){ this.wasSpecificVersionRequested = false; return; } this.wasSpecificVersionRequested = true; if (this.requestedVersion.equalsIgnoreCase(actualVersion)){ this.didSpecificVersionMatch = true; }else{ this.didSpecificVersionMatch = false; // redundant, already the default } } public boolean wasRequestedVersionRetrieved(){ if (this.wasSpecificVersionRequested && !this.didSpecificVersionMatch){ return false; } return true; } public DatasetVersion getDatasetVersion(){ return this.datasetVersionForResponse; } } // end RetrieveDatasetVersionResponse public DatasetVersion find(Object pk) { return (DatasetVersion) em.find(DatasetVersion.class, pk); } public DatasetVersion findByFriendlyVersionNumber(Long datasetId, String friendlyVersionNumber) { Long majorVersionNumber = null; Long minorVersionNumber = null; String[] versions = friendlyVersionNumber.split("\\."); try { if (versions.length == 1) { majorVersionNumber = Long.parseLong(versions[0]); } else if (versions.length == 2) { majorVersionNumber = Long.parseLong(versions[0]); minorVersionNumber = Long.parseLong(versions[1]); } else { return null; } } catch (NumberFormatException n) { return null; } if (majorVersionNumber != null && minorVersionNumber != null) { String queryStr = "SELECT v from DatasetVersion v where v.dataset.id = :datasetId and v.versionNumber= :majorVersionNumber and v.minorVersionNumber= :minorVersionNumber"; DatasetVersion foundDatasetVersion = null; try { Query query = em.createQuery(queryStr); query.setParameter("datasetId", datasetId); query.setParameter("majorVersionNumber", majorVersionNumber); query.setParameter("minorVersionNumber", minorVersionNumber); foundDatasetVersion = (DatasetVersion) query.getSingleResult(); } catch (javax.persistence.NoResultException e) { logger.warning("no ds version found: " + datasetId + " " + friendlyVersionNumber); // DO nothing, just return null. } return foundDatasetVersion; } if (majorVersionNumber == null && minorVersionNumber == null) { return null; } if (majorVersionNumber != null && minorVersionNumber == null) { try { TypedQuery<DatasetVersion> typedQuery = em.createQuery("SELECT v from DatasetVersion v where v.dataset.id = :datasetId and v.versionNumber= :majorVersionNumber", DatasetVersion.class); typedQuery.setParameter("datasetId", datasetId); typedQuery.setParameter("majorVersionNumber", majorVersionNumber); DatasetVersion retVal = null; List<DatasetVersion> versionsList = typedQuery.getResultList(); for (DatasetVersion dsvTest : versionsList) { if (retVal == null) { retVal = dsvTest; } else { if (retVal.getMinorVersionNumber().intValue() < dsvTest.getMinorVersionNumber().intValue()) { retVal = dsvTest; } } } return retVal; } catch (javax.persistence.NoResultException e) { logger.warning("no ds version found: " + datasetId + " " + friendlyVersionNumber); // DO nothing, just return null. } } return null; } /** * Parse a Persistent Id and return as 3 strings. * * Example: 1.0, 1.1. 3.4, etc. * * @param version * @return Long[] with [ major_version, minor_version ] * - either or both may be null */ public Long[] parseVersionNumber(String version){ if (version == null){ return null; } Long majorVersion; Long minorVersion = null; String[] vparts = version.split("\\."); if (vparts.length == 1){ try{ majorVersion = Long.parseLong(vparts[0]); }catch (NumberFormatException n) { return null; } }else if (vparts.length == 2){ try{ majorVersion = Long.parseLong(vparts[0]); minorVersion = Long.parseLong(vparts[1]); }catch (NumberFormatException n) { return null; } }else{ return null; } Long versionNumbers[] = { majorVersion, minorVersion }; return versionNumbers; } private void msg(String s){ //logger.fine(s); } /** * Does the version identifier in the URL ask for a "DRAFT"? * * @param version * @return boolean */ private boolean isVersionAskingForDraft(String version){ if (version == null){ return false; } return version.toUpperCase().equals(VersionState.DRAFT.toString()); } private String getDatasetVersionBasicQuery(String identifierClause, String extraClause){ if (identifierClause == null){ return null; } if (extraClause == null){ extraClause = ""; } String queryStr = "SELECT dv.* FROM DatasetVersion dv"; queryStr += " INNER JOIN Dataset ds"; queryStr += " ON dv.dataset_id=ds.id"; queryStr += identifierClause; // either persistentId or id queryStr += extraClause; // may be an empty string queryStr += " ORDER BY versionNumber DESC, minorVersionNumber DESC"; queryStr += " LIMIT 1;"; return queryStr; } /** * Query to return the last Released DatasetVersion by Persistent ID * * @param identifierClause - query clause to retrieve via DatasetVersion.Id or DatasetVersion.persistentId * @return String fullQuery */ private String getLatestReleasedDatasetVersionQuery(String identifierClause){ if (identifierClause == null){ return null; } String releasedClause = " AND dv.versionstate = '" + VersionState.RELEASED.toString() + "'"; return getDatasetVersionBasicQuery(identifierClause, releasedClause); } /** * Query to return a DatasetVersion by Specific Version * * @param identifierClause - query clause to retrieve via DatasetVersion.Id or DatasetVersion.persistentId * @return String fullQuery */ private String getNumericDatasetVersionQueryByIdentifier(String identifierClause, Long majorVersion, Long minorVersion){ if (identifierClause == null){ return null; } String extraQueryClause = ""; // For an exact version: retrieve either RELEASED or DEACCESSIONED // if (majorVersion != null && minorVersion != null){ extraQueryClause += " AND dv.versionNumber= " + majorVersion; extraQueryClause += " AND dv.minorVersionNumber= " + minorVersion; extraQueryClause += " AND (dv.versionstate = '" + VersionState.RELEASED.toString() + "' or dv.versionstate = '" + VersionState.DEACCESSIONED.toString() + "')"; } else { // Last released major version // extraQueryClause += " AND dv.versionNumber= " + majorVersion; extraQueryClause += " AND dv.versionstate = '" + VersionState.RELEASED.toString() + "'"; } return getDatasetVersionBasicQuery(identifierClause, extraQueryClause); } /** * Query to return a Draft DatasetVersion by Persistent ID * * @param identifierClause - query clause to retrieve via DatasetVersion.Id or DatasetVersion.persistentId * @return String fullQuery */ private String getDraftDatasetVersionQuery(String identifierClause){ if (identifierClause == null){ return null; } String draftClause = " AND dv.versionstate = '" + VersionState.DRAFT.toString() + "'"; return getDatasetVersionBasicQuery(identifierClause, draftClause); } /** * Query to return a DEACCESSIONED DatasetVersion by Persistent ID * * @param identifierClause - query clause to retrieve via DatasetVersion.Id or DatasetVersion.persistentId * @return String fullQuery */ private String getDeaccessionedDatasetVersionQuery(String identifierClause){ if (identifierClause == null){ return null; } String draftClause = " AND dv.versionstate = '" + VersionState.DEACCESSIONED.toString() + "'"; return getDatasetVersionBasicQuery(identifierClause, draftClause); } /** * Execute a query to return DatasetVersion * * @param queryString * @return */ private DatasetVersion getDatasetVersionByQuery(String queryString){ msg("getDatasetVersionByQuery queryString: " + queryString); if (queryString == null){ return null; } // Inexact check to see if one of the selected tables is DATASETVERSION // if (!queryString.toUpperCase().contains("FROM DATASETVERSION")){ throw new IllegalArgumentException("This query does not select from the table DATASETVERSION"); } try{ Query query = em.createNativeQuery(queryString, DatasetVersion.class); DatasetVersion ds = (DatasetVersion) query.getSingleResult(); msg("Found: " + ds); return ds; } catch (javax.persistence.NoResultException e) { msg("DatasetVersion not found: " + queryString); logger.log(Level.FINE, "DatasetVersion not found: {0}", queryString); return null; } catch (EJBException e) { logger.log(Level.WARNING, "EJBException exception: {0}", e.getMessage()); return null; } } // end getDatasetVersionByQuery public DatasetVersion retrieveDatasetVersionByIdentiferClause(String identifierClause, String version){ if (identifierClause == null){ return null; } DatasetVersion chosenVersion; /* -------------------------------------------- (1) Scenario: User asking for a DRAFT? - (1a) Look for draft - (1b) Not found: Get Latest Release - Permissions: check on DatasetPage -------------------------------------------- */ if (DatasetVersionServiceBean.this.isVersionAskingForDraft(version)){ // (1a) Try to retrieve a draft msg("(1a) Try to retrieve a draft"); String draftQuery = this.getDraftDatasetVersionQuery(identifierClause); chosenVersion = this.getDatasetVersionByQuery(draftQuery); // Draft Exists! Return it! msg("Draft Exists! Return it!"); if (chosenVersion != null){ return chosenVersion; // let DatasetPage check permissions } // (1b) No draft found - check for last released msg("(1b) No draft found - check for last released"); String lastReleasedQuery = this.getLatestReleasedDatasetVersionQuery(identifierClause); chosenVersion = this.getDatasetVersionByQuery(lastReleasedQuery); return chosenVersion; // This may be null -- let DatasetPage check } // END: User asking for a Draft /* -------------------------------------------- (2) Scenario: Version specified - (2a) Look for major and minor version - RELEASE OR DEACCESSIONED - OR Look for major version - RELEASE - (2c) Not found: look for latest released version - (2c) Not found: look for DEACCESSIONED - (2d) Not found: look for draft - Permissions: check on DatasetPage (3) Scenario: No version specified - Same as (2c)(2d) above - Permissions: check on DatasetPage -------------------------------------------- */ Long[] versionNumbers = parseVersionNumber(version); if (versionNumbers != null && versionNumbers.length == 2){ // At least a major version found // (2a) Look for major and minor version - RELEASE OR DEACCESSIONED msg("(2a) Look for major and minor version -" + Arrays.toString(versionNumbers)); String specificVersionQuery = this.getNumericDatasetVersionQueryByIdentifier(identifierClause, versionNumbers[0], versionNumbers[1]); chosenVersion = this.getDatasetVersionByQuery(specificVersionQuery); if (chosenVersion != null){ return chosenVersion; } } // (2b) Look for latest released version msg("(2b) Look for latest released version"); String latestVersionQuery = this.getLatestReleasedDatasetVersionQuery(identifierClause); //msg("latestVersionQuery: " + latestVersionQuery); chosenVersion = this.getDatasetVersionByQuery(latestVersionQuery); if (chosenVersion != null){ return chosenVersion; } // (2c) Look for DEACCESSIONED msg("(2c) Look for draft"); String dQuery = this.getDeaccessionedDatasetVersionQuery(identifierClause); //msg("draftQuery: " + draftQuery); chosenVersion = this.getDatasetVersionByQuery(dQuery); if (chosenVersion != null){ return chosenVersion; } // (2d) Look for draft msg("(2d) Look for draft"); String draftQuery = this.getDraftDatasetVersionQuery(identifierClause); //msg("draftQuery: " + draftQuery); chosenVersion = this.getDatasetVersionByQuery(draftQuery); return chosenVersion; // This may be null -- let DatasetPage check } // end: retrieveDatasetVersionByPersistentId /** * Find a DatasetVersion using the persisentID and version string * * @param persistentId doi:10.5072/FK2/BYM3IW * @param version "DRAFT", 1.0, 2, 3.4, null, etc * @return */ public RetrieveDatasetVersionResponse retrieveDatasetVersionByPersistentId(String persistentId, String version){ msg("retrieveDatasetVersionByPersistentId: " + persistentId + " " + version); if (persistentId==null){ return null; } /* Parse the persistent id */ GlobalId parsedId; try{ parsedId = new GlobalId(persistentId); // [ protocol, authority, identifier] } catch (IllegalArgumentException e){ logger.log(Level.WARNING, "Failed to parse persistentID: {0}", persistentId); return null; } String identifierClause = " AND ds.protocol= '" + parsedId.getProtocol() + "'"; identifierClause += " AND ds.authority = '" + parsedId.getAuthority() + "'"; identifierClause += " AND ds.identifier = '" + parsedId.getIdentifier() + "'"; DatasetVersion ds = retrieveDatasetVersionByIdentiferClause(identifierClause, version); if (ds != null){ msg("retrieved dataset: " + ds.getId() + " semantic: " + ds.getSemanticVersion()); return new RetrieveDatasetVersionResponse(ds, version); } return null; } /** * Find a DatasetVersion using the persisentID and version string * * @param datasetId * @param version "DRAFT", 1.0, 2, 3.4, null, etc * @return */ public RetrieveDatasetVersionResponse retrieveDatasetVersionById(Long datasetId, String version){ msg("retrieveDatasetVersionById: " + datasetId + " " + version); if (datasetId==null){ return null; } String identifierClause = " AND ds.id = " + datasetId; DatasetVersion ds = retrieveDatasetVersionByIdentiferClause(identifierClause, version); if (ds != null){ return new RetrieveDatasetVersionResponse(ds, version); } return null; } // end: retrieveDatasetVersionById /** * Find a DatasetVersion using the dataset versionId * * @param versionId DatasetVersion id * @return */ public RetrieveDatasetVersionResponse retrieveDatasetVersionByVersionId(Long versionId){ //msg("retrieveDatasetVersionById: " + datasetId + " " + versionId); if (versionId==null ){ return null; } // Try versionId - release state doesn't matte // String identifierClause = " and dv.id = " + versionId; String retrieveSpecifiedDSVQuery = getDatasetVersionBasicQuery(identifierClause, null); DatasetVersion chosenVersion = this.getDatasetVersionByQuery(retrieveSpecifiedDSVQuery); if (chosenVersion != null) { return new RetrieveDatasetVersionResponse(chosenVersion, ""); } return null; } // end: retrieveDatasetVersionByVersionId } // end class
