From 778947d20c808328da56c25c9e65a333cdf6a0fc Mon Sep 17 00:00:00 2001 From: ppodsednik Date: Sat, 21 Dec 2024 10:49:39 +0100 Subject: [PATCH] Refactor: RepesitoryAccess facade --- .../fedora/impl/AbstractRepositoryAccess.java | 491 ------ .../fedora/impl/RepositoryAccessImpl.java | 1317 +++++++++-------- .../fedora/impl/tmp/ResultMapper.java | 12 + .../fedora/impl/tmp/SolrQueryParameters.java | 15 + .../fedora/impl/tmp/SolrQueryService.java | 11 + .../fedora/impl/tmp/SolrQueryServiceImpl.java | 75 + .../impl/tmp/TmpAbstractRepositoryAccess.java | 277 ++++ .../kramerius/fedora/utils/TmpUtils.java | 239 +++ 8 files changed, 1302 insertions(+), 1135 deletions(-) delete mode 100644 shared/common/src/main/java/cz/incad/kramerius/fedora/impl/AbstractRepositoryAccess.java create mode 100644 shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/ResultMapper.java create mode 100644 shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/SolrQueryParameters.java create mode 100644 shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/SolrQueryService.java create mode 100644 shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/SolrQueryServiceImpl.java create mode 100644 shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/TmpAbstractRepositoryAccess.java create mode 100644 shared/common/src/main/java/cz/incad/kramerius/fedora/utils/TmpUtils.java diff --git a/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/AbstractRepositoryAccess.java b/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/AbstractRepositoryAccess.java deleted file mode 100644 index 14fe05c2c..000000000 --- a/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/AbstractRepositoryAccess.java +++ /dev/null @@ -1,491 +0,0 @@ -package cz.incad.kramerius.fedora.impl; - -import java.io.IOException; -import java.util.*; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.annotation.Nullable; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; - -import com.google.inject.name.Named; -import com.qbizm.kramerius.imp.jaxb.DigitalObject; -import cz.incad.kramerius.fedora.RepositoryAccess; -import cz.incad.kramerius.fedora.om.repository.RepositoryException; -import cz.incad.kramerius.fedora.om.repository.impl.AkubraDOManager; -import cz.incad.kramerius.fedora.om.repository.impl.AkubraRepositoryImpl; -import cz.incad.kramerius.fedora.om.resourceindex.ProcessingIndexFeeder; -import cz.incad.kramerius.statistics.accesslogs.AggregatedAccessLogs; -import org.dom4j.Namespace; -import org.ehcache.CacheManager; -import org.w3c.dom.DOMException; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import com.google.inject.Inject; - -import cz.incad.kramerius.FedoraNamespaceContext; -import cz.incad.kramerius.FedoraNamespaces; -import cz.incad.kramerius.ProcessSubtreeException; -import cz.incad.kramerius.TreeNodeProcessStackAware; -import cz.incad.kramerius.TreeNodeProcessor; -import cz.incad.kramerius.statistics.StatisticsAccessLog; -import cz.incad.kramerius.fedora.utils.FedoraUtils; -import cz.incad.kramerius.utils.XMLUtils; -import cz.incad.kramerius.utils.conf.KConfiguration; -import cz.incad.kramerius.fedora.utils.pid.LexerException; -import cz.incad.kramerius.fedora.utils.pid.PIDParser; - -public abstract class AbstractRepositoryAccess implements RepositoryAccess { - //---------------------- - public static final Logger LOGGER = Logger.getLogger(RepositoryApi.class.getName()); - - private static final Namespace NS_FOXML = new Namespace("foxml", "info:fedora/fedora-system:def/foxml#"); - private final AkubraRepositoryImpl akubraRepositoryImpl; - private final Unmarshaller digitalObjectUnmarshaller; - //------------------------------------------------------------------------- - - public static final Logger LOGGER = Logger.getLogger(AbstractRepositoryAccess.class.getName()); - protected XPathFactory xPathFactory; - protected KConfiguration configuration = KConfiguration.getInstance(); - - @Inject - public AbstractRepositoryAccess(@Nullable StatisticsAccessLog accessLog) - throws IOException { - super(); - this.xPathFactory = XPathFactory.newInstance(); - } - - protected String makeSureObjectPid(String pid) throws LexerException { - PIDParser pidParser = new PIDParser(pid); - pidParser.objectPid(); - String sureObjectPid = pidParser.isPagePid() ? pidParser.getParentObjectPid() : pidParser.getObjectPid(); - return sureObjectPid; - } - - @Override - public String getDonator(Document relsExt) { - try { - Element foundElement = XMLUtils.findElement(relsExt.getDocumentElement(), "hasDonator", - FedoraNamespaces.KRAMERIUS_URI); - if (foundElement != null) { - String sform = foundElement.getAttributeNS(FedoraNamespaces.RDF_NAMESPACE_URI, "resource"); - PIDParser pidParser = new PIDParser(sform); - pidParser.disseminationURI(); - return pidParser.getObjectId(); - } else { - return ""; - } - } catch (DOMException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - throw new IllegalArgumentException(e); - } catch (LexerException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - throw new IllegalArgumentException(e); - } - } - - protected void changeStack(TreeNodeProcessor processor, Stack pidStack) { - if (processor instanceof TreeNodeProcessStackAware) { - TreeNodeProcessStackAware stackAware = (TreeNodeProcessStackAware) processor; - stackAware.changeProcessingStack(pidStack); - } - } - - protected boolean processSubtreeInternal(String pid, Document relsExt, TreeNodeProcessor processor, int level, - Stack pidStack) - throws XPathExpressionException, LexerException, IOException, ProcessSubtreeException { - processor.process(pid, level); - boolean breakProcessing = processor.breakProcessing(pid, level); - if (breakProcessing) { - return breakProcessing; - } - if (relsExt == null) { - return false; - } - XPathFactory factory = this.xPathFactory; - XPath xpath = factory.newXPath(); - xpath.setNamespaceContext(new FedoraNamespaceContext()); - XPathExpression expr = xpath.compile("/rdf:RDF/rdf:Description/*"); - NodeList nodes = (NodeList) expr.evaluate(relsExt, XPathConstants.NODESET); - - if (pidStack.contains(pid)) { - LOGGER.log(Level.WARNING, "Cyclic reference on " + pid); - return breakProcessing; - } - pidStack.push(pid); - changeStack(processor, pidStack); - for (int i = 0, ll = nodes.getLength(); i < ll; i++) { - Node node = nodes.item(i); - if (node.getNodeType() == Node.ELEMENT_NODE) { - Element iteratingElm = (Element) node; - String namespaceURI = iteratingElm.getNamespaceURI(); - if (namespaceURI != null && (namespaceURI.equals(FedoraNamespaces.ONTOLOGY_RELATIONSHIP_NAMESPACE_URI) - || namespaceURI.equals(FedoraNamespaces.RDF_NAMESPACE_URI))) { - String attVal = iteratingElm.getAttributeNS(FedoraNamespaces.RDF_NAMESPACE_URI, "resource"); - if (!attVal.trim().equals("")) { - PIDParser pidParser = new PIDParser(attVal); - pidParser.disseminationURI(); - String objectId = pidParser.getObjectPid(); - if (pidParser.getNamespaceId().equals("uuid")) { - if (!processor.skipBranch(objectId, level + 1)) { - Document iterationgRelsExt = null; - - try { - iterationgRelsExt = getRelsExt(objectId); - } catch (Exception ex) { - LOGGER.warning("could not read RELS-EXT, skipping branch [" + (level + 1) - + "] and pid (" + objectId + "):" + ex); - } - breakProcessing = processSubtreeInternal(pidParser.getObjectPid(), iterationgRelsExt, - processor, level + 1, pidStack); - - if (breakProcessing) { - break; - } - } else { - LOGGER.fine("skipping branch [" + (level + 1) + "] and pid (" + objectId + ")"); - } - } - } - - } - } - } - pidStack.pop(); - changeStack(processor, pidStack); - return breakProcessing; - } - - @Override - public void processSubtree(String pid, TreeNodeProcessor processor) throws ProcessSubtreeException, IOException { - try { - pid = makeSureObjectPid(pid); - Document relsExt = null; - try { - // should be from - if (isStreamAvailable(pid, FedoraUtils.RELS_EXT_STREAM)) { - relsExt = getRelsExt(pid); - } else { - LOGGER.warning("could not read root RELS-EXT, skipping object (" + pid + ")"); - } - } catch (Exception ex) { - LOGGER.warning("could not read root RELS-EXT, skipping object (" + pid + "):" + ex); - } - if (!processor.skipBranch(pid, 0)) { - processSubtreeInternal(pid, relsExt, processor, 0, new Stack()); - } - } catch (LexerException e) { - LOGGER.warning("Error in pid: " + pid); - throw new ProcessSubtreeException(e); - } catch (XPathExpressionException e) { - throw new ProcessSubtreeException(e); - } - } - - @Override - public List getPids(String pid) throws IOException { - final List retval = new ArrayList<>(); - try { - processSubtree(pid, new TreeNodeProcessor() { - @Override - public void process(String pid, int level) { - retval.add(pid); - } - - @Override - public boolean breakProcessing(String pid, int level) { - return false; - } - - @Override - public boolean skipBranch(String pid, int level) { - return false; - } - }); - } catch (ProcessSubtreeException e) { - throw new IOException(e); - } - return retval; - } - - @Override - public String findFirstViewablePid(String pid) throws IOException { - final List foundPids = new ArrayList(); - try { - processSubtree(makeSureObjectPid(pid), new TreeNodeProcessor() { - boolean breakProcess = false; - int previousLevel = 0; - - @Override - public boolean breakProcessing(String pid, int level) { - return breakProcess; - } - - @Override - public boolean skipBranch(String pid, int level) { - return false; - } - - @Override - public void process(String pid, int level) throws ProcessSubtreeException { - try { - if (previousLevel < level || level == 0) { - if (AbstractRepositoryAccess.this.isImageFULLAvailable(pid)) { - foundPids.add(pid); - breakProcess = true; - } - } else if (previousLevel > level) { - breakProcess = true; - } else if ((previousLevel == level) && (level != 0)) { - breakProcess = true; - } - previousLevel = level; - } catch (Exception e) { - throw new ProcessSubtreeException(e); - } - } - }); - } catch (ProcessSubtreeException e) { - throw new IOException(e); - } catch (LexerException e) { - throw new IOException(e); - } - - return foundPids.isEmpty() ? null : foundPids.get(0); - } - - @Override - public String getKrameriusModelName(Document relsExt) throws IOException { - try { - //TODO: Duplicate code in RelsExt helper -> mn - Element foundElement = XMLUtils.findElement(relsExt.getDocumentElement(), "hasModel", FedoraNamespaces.FEDORA_MODELS_URI); - if (foundElement != null) { - String sform = foundElement.getAttributeNS(FedoraNamespaces.RDF_NAMESPACE_URI, "resource"); - PIDParser pidParser = new PIDParser(sform); - pidParser.disseminationURI(); - return pidParser.getObjectId(); - } else { - throw new IllegalArgumentException("cannot find model of given document"); - } - } catch (DOMException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - throw new IllegalArgumentException(e); - } catch (LexerException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - throw new IllegalArgumentException(e); - } - } - - @Override - public String getDonator(String pid) throws IOException { - return getDonator(getRelsExt(pid)); - } - - @Override - public String getKrameriusModelName(String pid) throws IOException { - return getKrameriusModelName(getRelsExt(pid)); - } - - @Override - public List getPages(String pid, boolean deep) throws IOException { - Document relsExt = getRelsExt(pid); - return getPages(pid, relsExt.getDocumentElement()); - } - - @Override - public String getFirstItemPid(Document relsExt) - throws IOException { - try { - Element foundElement = XMLUtils.findElement(relsExt.getDocumentElement(), "hasItem", FedoraNamespaces.KRAMERIUS_URI); - if (foundElement != null) { - String sform = foundElement.getAttributeNS(FedoraNamespaces.RDF_NAMESPACE_URI, "resource"); - PIDParser pidParser = new PIDParser(sform); - pidParser.disseminationURI(); - String pidItem = "uuid:" + pidParser.getObjectId(); - return pidItem; - } else { - return ""; - } - } catch (DOMException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - throw new IllegalArgumentException(e); - } catch (LexerException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - throw new IllegalArgumentException(e); - } - } - - @Override - public String getFirstItemPid(String pid) throws IOException { - Document relsExt = getRelsExt(pid); - return getFirstItemPid(relsExt); - } - - @Override - public String getFirstVolumePid(Document relsExt) throws IOException { - - try { - Element foundElement = XMLUtils.findElement(relsExt.getDocumentElement(), "hasVolume", FedoraNamespaces.KRAMERIUS_URI); - if (foundElement != null) { - String sform = foundElement.getAttributeNS(FedoraNamespaces.RDF_NAMESPACE_URI, "resource"); - PIDParser pidParser = new PIDParser(sform); - pidParser.disseminationURI(); - String pidVolume = "uuid:" + pidParser.getObjectId(); - return pidVolume; - } else { - return ""; - } - } catch (DOMException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - throw new IllegalArgumentException(e); - } catch (LexerException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - throw new IllegalArgumentException(e); - } - } - - @Override - public String getFirstVolumePid(String pid) throws IOException { - Document relsExt = getRelsExt(pid); - return getFirstVolumePid(relsExt); - } - - @Override - public boolean isImageFULLAvailable(String pid) throws IOException { - try { - return isStreamAvailable(makeSureObjectPid(pid), FedoraUtils.IMG_FULL_STREAM); - } catch (LexerException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - throw new IOException(e); - } - } - - @Override - public List getPages(String pid, Element rootElementOfRelsExt) throws IOException { - try { - ArrayList elms = new ArrayList(); - String xPathStr = "/RDF/Description/hasPage"; - XPath xpath = this.xPathFactory.newXPath(); - XPathExpression expr = xpath.compile(xPathStr); - NodeList nodes = (NodeList) expr.evaluate(rootElementOfRelsExt, XPathConstants.NODESET); - for (int i = 0, lastIndex = nodes.getLength() - 1; i <= lastIndex; i++) { - Element elm = (Element) nodes.item(i); - elms.add(elm); - } - return elms; - } catch (XPathExpressionException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - throw new IOException(e); - } - } - - protected List getTreePredicates() { - return Arrays.asList(KConfiguration.getInstance().getPropertyList("fedora.treePredicates")); - } - - @Override - public boolean getFirstViewablePath(List pids, List models) throws IOException { - try { - String pid = pids.get(pids.size() - 1); - pid = makeSureObjectPid(pid); - if (isImageFULLAvailable(pid)) { - return true; - } - Document relsExt = getRelsExt(pid); - Element descEl = XMLUtils.findElement(relsExt.getDocumentElement(), "Description", - FedoraNamespaces.RDF_NAMESPACE_URI); - List els = XMLUtils.getElements(descEl); - for (Element el : els) { - if (getTreePredicates().contains(el.getLocalName())) { - if (el.hasAttribute("rdf:resource")) { - pid = el.getAttributes().getNamedItem("rdf:resource").getNodeValue(); - pids.add(pid); - models.add(getKrameriusModelName(pid)); - if (getFirstViewablePath(pids, models)) { - return true; - } else { - pids.remove(pids.size() - 1); - models.remove(pids.size() - 1); - } - } - } - } - return false; - } catch (DOMException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - throw new IOException(e); - } catch (LexerException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - throw new IOException(e); - } - } - - @Override - public List getModelsOfRel(Document relsExt) { - try { - throw new UnsupportedOperationException("still unsupported"); - // Element foundElement = - // XMLUtils.findElement(relsExt.getDocumentElement(), "hasModel", - // FedoraNamespaces.FEDORA_MODELS_URI); - // if (foundElement != null) { - // String sform = - // foundElement.getAttributeNS(FedoraNamespaces.RDF_NAMESPACE_URI, - // "resource"); - // PIDParser pidParser = new PIDParser(sform); - // pidParser.disseminationURI(); - // ArrayList model = - // RelsExtModelsMap.getModelsOfRelation(pidParser.getObjectId()); - // return model; - // } else { - // throw new IllegalArgumentException("cannot find model of "); - // } - } catch (DOMException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - throw new IllegalArgumentException(e); - } - } - - @Override - public List getModelsOfRel(String pid) throws IOException { - return getModelsOfRel(getRelsExt(pid)); - } -// RepoApiImpl------------------------------------------------------------------------------------------- -@Inject -public RepositoryApiImpl(ProcessingIndexFeeder processingIndexFeeder, @Named("akubraCacheManager") CacheManager cacheManager) throws RepositoryException { - try { - AkubraDOManager akubraDOManager = new AkubraDOManager(cacheManager); - this.akubraRepositoryImpl = (AkubraRepositoryImpl) AkubraRepositoryImpl.build(processingIndexFeeder, akubraDOManager); - this.digitalObjectUnmarshaller = JAXBContext.newInstance(DigitalObject.class).createUnmarshaller(); - } catch (IOException e) { - throw new RepositoryException(e); - } catch (JAXBException e) { - throw new RepositoryException("Error initializing JAXB unmarshaller for " + DigitalObject.class.getName()); - } -} - - - //--------- KraRepositoryAPIIMPl - @javax.inject.Inject - private RepositoryApiImpl repositoryApi; - - @javax.inject.Inject - private AggregatedAccessLogs accessLog; - - - @Override - public RepositoryApi getLowLevelApi() { - return repositoryApi; - } - - -} diff --git a/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/RepositoryAccessImpl.java b/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/RepositoryAccessImpl.java index 828b351e2..553166ad8 100644 --- a/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/RepositoryAccessImpl.java +++ b/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/RepositoryAccessImpl.java @@ -5,6 +5,7 @@ import com.qbizm.kramerius.imp.jaxb.DatastreamVersionType; import com.qbizm.kramerius.imp.jaxb.DigitalObject; import cz.incad.kramerius.StreamHeadersObserver; +import cz.incad.kramerius.fedora.RepositoryAccess; import cz.incad.kramerius.fedora.om.repository.AkubraRepository; import cz.incad.kramerius.fedora.om.repository.RepositoryDatastream; import cz.incad.kramerius.fedora.om.repository.RepositoryException; @@ -45,7 +46,7 @@ import java.util.logging.Level; import java.util.stream.Collectors; -public class RepositoryAccessImpl extends AbstractRepositoryAccess { +public class RepositoryAccessImpl implements RepositoryAccess { private AkubraDOManager manager; private AkubraRepository repository; @@ -67,94 +68,79 @@ public RepositoryAccessImpl(ProcessingIndexFeeder feeder, @Nullable AggregatedAc } } - // ------------- get info related to an object's stream + //-------- get object property @Override - public String getExternalStreamURL(String pid, String datastreamName) throws IOException { - DigitalObject object = manager.readObjectFromStorage(pid); - if (object != null) { + public String getProperty(String pid, String propertyName) throws IOException, RepositoryException { + org.dom4j.Document objectFoxml = getFoxml(pid); + return objectFoxml == null ? null : extractProperty(objectFoxml, propertyName); + } - DatastreamVersionType stream = AkubraUtils.getLastStreamVersion(object, datastreamName); + private String extractProperty(org.dom4j.Document foxmlDoc, String name) { + org.dom4j.Node node = Dom4jUtils.buildXpath(String.format("/foxml:digitalObject/foxml:objectProperties/foxml:property[@NAME='%s']/@VALUE", name)).selectSingleNode(foxmlDoc); + return node == null ? null : Dom4jUtils.toStringOrNull(node); + } - if (stream != null) { - if (stream.getContentLocation() != null && "URL".equals(stream.getContentLocation().getTYPE())) { - return stream.getContentLocation().getREF(); - } else { - throw new IOException("Expected external datastream: " + pid + " - " + datastreamName); - } + @Override + public String getPropertyLabel(String pid) throws IOException, RepositoryException { + return getProperty(pid, "info:fedora/fedora-system:def/model#label"); + } + + @Override + public LocalDateTime getPropertyCreated(String pid) throws IOException, RepositoryException { + String propertyValue = getProperty(pid, "info:fedora/fedora-system:def/model#createdDate"); + if (propertyValue != null) { + try { + return LocalDateTime.parse(propertyValue, RepositoryApi.TIMESTAMP_FORMATTER); + } catch (DateTimeParseException e) { + System.out.println(String.format("cannot parse createdDate %s from object %s", propertyValue, pid)); } - throw new IOException("Datastream not found: " + pid + " - " + datastreamName); } - throw new IOException("Object not found: " + pid); + return null; } @Override - public List> getStreamsOfObject(String pid) throws IOException { - try { - List> results = new ArrayList<>(); - DigitalObject obj = manager.readObjectFromStorage(pid); - - return obj.getDatastream().stream().filter((o) -> { - try { - // policy stream -> should be ommited? - return (!o.getID().equals("POLICY")); - } catch (Exception e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - return false; - } - }).map((o) -> { - Map map = null; - try { - map = createMap(o.getID()); - List datastreamVersionList = o.getDatastreamVersion(); - map.put("mimetype", datastreamVersionList.get(datastreamVersionList.size() - 1).getMIMETYPE()); - } catch (Exception e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - } - return map; - }).collect(Collectors.toList()); - } catch (Exception e) { - throw new IOException(e); + public LocalDateTime getPropertyLastModified(String pid) throws IOException, RepositoryException { + String propertyValue = getProperty(pid, "info:fedora/fedora-system:def/view#lastModifiedDate"); + if (propertyValue != null) { + try { + return LocalDateTime.parse(propertyValue, RepositoryApi.TIMESTAMP_FORMATTER); + } catch (DateTimeParseException e) { + System.out.println(String.format("cannot parse lastModifiedDate %s from object %s", propertyValue, pid)); + } } + return null; } - @Override - public String getMimeTypeForStream(String pid, String streamName) throws IOException { + public Date getObjectLastmodifiedFlag(String pid) throws IOException { DigitalObject object = manager.readObjectFromStorage(pid); if (object != null) { - DatastreamVersionType stream = AkubraUtils.getLastStreamVersion(object, streamName); - if (stream != null) { - return stream.getMIMETYPE(); - } - throw new IOException("Datastream not found: " + pid + " - " + streamName); + return AkubraUtils.getLastModified(object); } throw new IOException("Object not found: " + pid); } + @Override - public boolean isStreamAvailable(String pid, String streamName) throws IOException { + public boolean isObjectAvailable(String pid) throws IOException { try { - DigitalObject object = manager.readObjectFromStorage(pid); - return AkubraUtils.streamExists(object, streamName); - } catch (Exception e) { + return this.repository.objectExists(pid); + } catch (RepositoryException e) { throw new IOException(e); } } - @Override - public Date getStreamLastmodifiedFlag(String pid, String streamName) throws IOException { - DigitalObject object = manager.readObjectFromStorage(pid); - if (object != null) { - DatastreamVersionType stream = AkubraUtils.getLastStreamVersion(object, streamName); - if (stream != null) { - if (stream.getCREATED() == null) { - return new Date(); - } else { - return stream.getCREATED().toGregorianCalendar().getTime(); - } - } - throw new IOException("Datastream not found: " + pid + " - " + streamName); + public boolean objectExists(String pid) throws RepositoryException { + Lock readLock = AkubraDOManager.getReadLock(pid); + try { + return akubraRepositoryImpl.objectExists(pid); + } finally { + readLock.unlock(); } - throw new IOException("Object not found: " + pid); + } + + @Override + public String getFedoraVersion() throws IOException { + return "Akubra"; } @Override @@ -171,88 +157,398 @@ public InputStream getFoxml(String pid, boolean archive) throws IOException { throw new IOException(e); } } + @Override + public org.dom4j.Document getFoxml(String pid) throws RepositoryException, IOException { + Lock readLock = AkubraDOManager.getReadLock(pid); + try { + RepositoryObject object = akubraRepositoryImpl.getObject(pid); + return Utils.inputstreamToDocument(object.getFoxml(), true); + } finally { + readLock.unlock(); + } + } + // ------------- get metadata related to a pid's stream + @Override + public List getDatastreamNames(String pid) throws RepositoryException, IOException, SolrServerException { + Lock readLock = AkubraDOManager.getReadLock(pid); + try { + RepositoryObject object = akubraRepositoryImpl.getObject(pid); + List streams = object.getStreams(); + return streams.stream().map(it -> { + try { + return it.getName(); + } catch (RepositoryException e) { + LOGGER.log(Level.SEVERE,e.getMessage(),e); + return null; + } + }).collect(Collectors.toList()); + } finally { + readLock.unlock(); + } + } @Override - public Document getBiblioMods(String pid) throws IOException { + public boolean datastreamExists(String pid, String dsId) throws RepositoryException, IOException { + Lock readLock = AkubraDOManager.getReadLock(pid); try { - return getStream(makeSureObjectPid(pid), FedoraUtils.BIBLIO_MODS_STREAM); - } catch (LexerException e) { - throw new IOException(e); + RepositoryObject object = akubraRepositoryImpl.getObject(pid); + return object == null ? false : object.streamExists(dsId); + } finally { + readLock.unlock(); } } @Override - public Document getRelsExt(String pid) throws IOException { + public String getDatastreamMimetype(String pid, String dsId) throws RepositoryException, IOException { + Lock readLock = AkubraDOManager.getReadLock(pid); try { - // consider to change to metadata - return getStream(makeSureObjectPid(pid), FedoraUtils.RELS_EXT_STREAM); - } catch (LexerException e) { - throw new IOException(e); + RepositoryObject object = akubraRepositoryImpl.getObject(pid); + if (object != null) { + RepositoryDatastream stream = object.getStream(dsId); + if (stream != null) { + return stream.getMimeType(); + } + } + return null; + } finally { + readLock.unlock(); } } @Override - public Document getDC(String pid) throws IOException { + public org.dom4j.Document getDatastreamXml(String pid, String dsId) throws RepositoryException, IOException { + Lock readLock = AkubraDOManager.getReadLock(pid); try { - return getStream(makeSureObjectPid(pid), FedoraUtils.DC_STREAM); - } catch (LexerException e) { - throw new IOException(e); + RepositoryObject object = akubraRepositoryImpl.getObject(pid); + if (object.streamExists(dsId)) { + org.dom4j.Document foxml = Utils.inputstreamToDocument(object.getFoxml(), true); + org.dom4j.Element dcEl = (org.dom4j.Element) Dom4jUtils.buildXpath(String.format("/foxml:digitalObject/foxml:datastream[@ID='%s']", dsId)).selectSingleNode(foxml); + org.dom4j.Element detached = (org.dom4j.Element) dcEl.detach(); + org.dom4j.Document result = DocumentHelper.createDocument(); + result.add(detached); + return result; + } else { + return null; + } + } finally { + readLock.unlock(); + } + } + + public String getTypeOfDatastream(String pid, String dsId) throws RepositoryException, IOException { + Lock readLock = AkubraDOManager.getReadLock(pid); + try { + RepositoryObject object = akubraRepositoryImpl.getObject(pid); + if (object.streamExists(dsId)) { + RepositoryDatastream stream = object.getStream(dsId); + return stream.getStreamType().name(); + } else { + return null; + } + } finally { + readLock.unlock(); } } - // -------- image content @Override - public boolean isImageFULLAvailable(String pid) throws IOException { - return super.isImageFULLAvailable(pid); + public InputStream getLatestVersionOfDatastream(String pid, String dsId) throws RepositoryException, IOException { + Lock readLock = AkubraDOManager.getReadLock(pid); + try { + RepositoryObject object = akubraRepositoryImpl.getObject(pid); + if (object.streamExists(dsId)) { + RepositoryDatastream stream = object.getStream(dsId); + return stream.getContent(); + } else { + return null; + } + } finally { + readLock.unlock(); + } } @Override - public boolean isContentAccessible(String pid) throws IOException { - return true; + public org.dom4j.Document getLatestVersionOfInlineXmlDatastream(String pid, String dsId) throws RepositoryException, IOException { + InputStream is = getLatestVersionOfDatastream(pid, dsId); + return is == null ? null : Utils.inputstreamToDocument(is, true); } @Override - public boolean isFullthumbnailAvailable(String pid) throws IOException { - return this.isStreamAvailable(pid, FedoraUtils.IMG_PREVIEW_STREAM); + public String getLatestVersionOfManagedTextDatastream(String pid, String dsId) throws RepositoryException, IOException { + InputStream is = getLatestVersionOfDatastream(pid, dsId); + return is == null ? null : Utils.inputstreamToString(is); } @Override - public String getFullThumbnailMimeType(String pid) throws IOException { - return getMimeTypeForStream(pid, FedoraUtils.IMG_PREVIEW_STREAM); + public boolean isRelsExtAvailable(String pid) throws IOException, RepositoryException { + return repositoryApi.datastreamExists(pid, KnownDatastreams.RELS_EXT.toString()); } @Override - public String getSmallThumbnailMimeType(String pid) throws IOException, XPathExpressionException { - return getMimeTypeForStream(pid, FedoraUtils.IMG_THUMB_STREAM); + public org.dom4j.Document getRelsExt(String pid, boolean namespaceAware) throws IOException, RepositoryException { + org.dom4j.Document doc = repositoryApi.getLatestVersionOfInlineXmlDatastream(pid, KnownDatastreams.RELS_EXT.toString()); + if (doc != null && !namespaceAware) { + doc.accept(new NamespaceRemovingVisitor(true, true)); + } + return doc; } @Override - public InputStream getFullThumbnail(String pid) throws IOException { - try { - return getDataStream(makeSureObjectPid(pid), FedoraUtils.IMG_PREVIEW_STREAM); - } catch (LexerException e) { - throw new IOException(e); + public boolean isModsAvailable(String pid) throws IOException, RepositoryException { + return repositoryApi.datastreamExists(pid, KnownDatastreams.BIBLIO_MODS.toString()); + } + + @Override + public org.dom4j.Document getMods(String pid, boolean namespaceAware) throws IOException, RepositoryException { + org.dom4j.Document doc = repositoryApi.getLatestVersionOfInlineXmlDatastream(pid, KnownDatastreams.BIBLIO_MODS.toString()); + if (doc != null && !namespaceAware) { + doc.accept(new NamespaceRemovingVisitor(true, true)); } + return doc; } @Override - public InputStream getSmallThumbnail(String pid) throws IOException { + public boolean isDublinCoreAvailable(String pid) throws IOException, RepositoryException { + return repositoryApi.datastreamExists(pid, KnownDatastreams.BIBLIO_DC.toString()); + } + + @Override + public org.dom4j.Document getDublinCore(String pid, boolean namespaceAware) throws IOException, RepositoryException { + org.dom4j.Document doc = repositoryApi.getLatestVersionOfInlineXmlDatastream(pid, KnownDatastreams.BIBLIO_DC.toString()); + if (doc != null && !namespaceAware) { + doc.accept(new NamespaceRemovingVisitor(true, true)); + } + return doc; + } + + @Override + public boolean isOcrTextAvailable(String pid) throws IOException, RepositoryException { + return repositoryApi.datastreamExists(pid, KnownDatastreams.OCR_TEXT.toString()); + } + + @Override + public String getOcrText(String pid) throws IOException, RepositoryException { + return repositoryApi.getLatestVersionOfManagedTextDatastream(pid, KnownDatastreams.OCR_TEXT.toString()); + } + + @Override + public boolean isOcrAltoAvailable(String pid) throws IOException, RepositoryException { + return repositoryApi.datastreamExists(pid, KnownDatastreams.OCR_ALTO.toString()); + } + + @Override + public org.dom4j.Document getOcrAlto(String pid, boolean namespaceAware) throws IOException, RepositoryException { + org.dom4j.Document doc = repositoryApi.getLatestVersionOfInlineXmlDatastream(pid, KnownDatastreams.OCR_ALTO.toString()); + if (doc != null && !namespaceAware) { + doc.accept(new NamespaceRemovingVisitor(true, true)); + } + return doc; + } + + @Override + public boolean isImgFullAvailable(String pid) throws IOException, RepositoryException { + return repositoryApi.datastreamExists(pid, KnownDatastreams.IMG_FULL.toString()); + } + + @Override + public String getImgFullMimetype(String pid) throws IOException, RepositoryException { + return repositoryApi.getDatastreamMimetype(pid, KnownDatastreams.IMG_FULL.toString()); + } + + @Override + public InputStream getImgFull(String pid) throws IOException, RepositoryException { + this.accessLog.reportAccess(pid, KnownDatastreams.IMG_FULL.toString()); + return repositoryApi.getLatestVersionOfDatastream(pid, KnownDatastreams.IMG_FULL.toString()); + } + + @Override + public boolean isImgThumbAvailable(String pid) throws IOException, RepositoryException { + return repositoryApi.datastreamExists(pid, KnownDatastreams.IMG_THUMB.toString()); + } + + @Override + public String getImgThumbMimetype(String pid) throws IOException, RepositoryException { + return repositoryApi.getDatastreamMimetype(pid, KnownDatastreams.IMG_THUMB.toString()); + } + + @Override + public InputStream getImgThumb(String pid) throws IOException, RepositoryException { + return repositoryApi.getLatestVersionOfDatastream(pid, KnownDatastreams.IMG_THUMB.toString()); + } + + @Override + public boolean isImgPreviewAvailable(String pid) throws IOException, RepositoryException { + return repositoryApi.datastreamExists(pid, KnownDatastreams.IMG_PREVIEW.toString()); + } + + @Override + public String getImgPreviewMimetype(String pid) throws IOException, RepositoryException { + return repositoryApi.getDatastreamMimetype(pid, KnownDatastreams.IMG_PREVIEW.toString()); + } + + @Override + public InputStream getImgPreview(String pid) throws IOException, RepositoryException { + this.accessLog.reportAccess(pid, KnownDatastreams.IMG_PREVIEW.toString()); + return repositoryApi.getLatestVersionOfDatastream(pid, KnownDatastreams.IMG_PREVIEW.toString()); + } + + @Override + public boolean isAudioMp3Available(String pid) throws IOException, RepositoryException { + return repositoryApi.datastreamExists(pid, KnownDatastreams.AUDIO_MP3.toString()); + } + + @Override + public String getAudioMp3Mimetype(String pid) throws IOException, RepositoryException { + return repositoryApi.getDatastreamMimetype(pid, KnownDatastreams.AUDIO_MP3.toString()); + } + + @Override + public InputStream getAudioMp3(String pid) throws IOException, RepositoryException { + this.accessLog.reportAccess(pid, KnownDatastreams.AUDIO_MP3.toString()); + return repositoryApi.getLatestVersionOfDatastream(pid, KnownDatastreams.AUDIO_MP3.toString()); + } + + @Override + public boolean isAudioOggAvailable(String pid) throws IOException, RepositoryException { + return repositoryApi.datastreamExists(pid, KnownDatastreams.AUDIO_OGG.toString()); + } + + @Override + public String getAudioOggMimetype(String pid) throws IOException, RepositoryException { + return repositoryApi.getDatastreamMimetype(pid, KnownDatastreams.AUDIO_OGG.toString()); + } + + @Override + public InputStream getAudioOgg(String pid) throws IOException, RepositoryException { + this.accessLog.reportAccess(pid, KnownDatastreams.AUDIO_OGG.toString()); + return repositoryApi.getLatestVersionOfDatastream(pid, KnownDatastreams.AUDIO_OGG.toString()); + } + + @Override + public boolean isAudioWavAvailable(String pid) throws IOException, RepositoryException { + return repositoryApi.datastreamExists(pid, KnownDatastreams.AUDIO_WAV.toString()); + } + + @Override + public String getAudioWavMimetype(String pid) throws IOException, RepositoryException { + return repositoryApi.getDatastreamMimetype(pid, KnownDatastreams.AUDIO_WAV.toString()); + } + + @Override + public InputStream getAudioWav(String pid) throws IOException, RepositoryException { + return repositoryApi.getLatestVersionOfDatastream(pid, KnownDatastreams.AUDIO_WAV.toString()); + } + + @Override + public String getModel(String objectPid) throws RepositoryException, IOException, SolrServerException { + Map description = repositoryApi.getDescription(objectPid); + String model = description.get("model"); + return model == null ? null : model.substring("model:".length()); + } + + @Override + public boolean isStreamAvailable(String pid, String streamName) throws IOException { try { - return getDataStream(makeSureObjectPid(pid), FedoraUtils.IMG_THUMB_STREAM); - } catch (LexerException e) { + DigitalObject object = manager.readObjectFromStorage(pid); + return AkubraUtils.streamExists(object, streamName); + } catch (Exception e) { throw new IOException(e); } } @Override - public String getImageFULLMimeType(String pid) throws IOException, XPathExpressionException { - return getMimeTypeForStream(pid, FedoraUtils.IMG_FULL_STREAM); + public String getExternalStreamURL(String pid, String datastreamName) throws IOException { + DigitalObject object = manager.readObjectFromStorage(pid); + if (object != null) { + + DatastreamVersionType stream = AkubraUtils.getLastStreamVersion(object, datastreamName); + + if (stream != null) { + if (stream.getContentLocation() != null && "URL".equals(stream.getContentLocation().getTYPE())) { + return stream.getContentLocation().getREF(); + } else { + throw new IOException("Expected external datastream: " + pid + " - " + datastreamName); + } + } + throw new IOException("Datastream not found: " + pid + " - " + datastreamName); + } + throw new IOException("Object not found: " + pid); + } + + @Override + public String getMimeTypeForStream(String pid, String streamName) throws IOException { + DigitalObject object = manager.readObjectFromStorage(pid); + if (object != null) { + DatastreamVersionType stream = AkubraUtils.getLastStreamVersion(object, streamName); + if (stream != null) { + return stream.getMIMETYPE(); + } + throw new IOException("Datastream not found: " + pid + " - " + streamName); + } + throw new IOException("Object not found: " + pid); + } + + @Override + public Date getStreamLastmodifiedFlag(String pid, String streamName) throws IOException { + DigitalObject object = manager.readObjectFromStorage(pid); + if (object != null) { + DatastreamVersionType stream = AkubraUtils.getLastStreamVersion(object, streamName); + if (stream != null) { + if (stream.getCREATED() == null) { + return new Date(); + } else { + return stream.getCREATED().toGregorianCalendar().getTime(); + } + } + throw new IOException("Datastream not found: " + pid + " - " + streamName); + } + throw new IOException("Object not found: " + pid); + } + + @Override + public List> getStreamsOfObject(String pid) throws IOException { + try { + List> results = new ArrayList<>(); + DigitalObject obj = manager.readObjectFromStorage(pid); + + return obj.getDatastream().stream().filter((o) -> { + try { + // policy stream -> should be ommited? + return (!o.getID().equals("POLICY")); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + return false; + } + }).map((o) -> { + Map map = null; + try { + map = createMap(o.getID()); + List datastreamVersionList = o.getDatastreamVersion(); + map.put("mimetype", datastreamVersionList.get(datastreamVersionList.size() - 1).getMIMETYPE()); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + } + return map; + }).collect(Collectors.toList()); + } catch (Exception e) { + throw new IOException(e); + } + } + private Map createMap(String label) { + Map map = new HashMap(); + map.put("dsid", label); + map.put("label", label); + return map; } + + + // -------- stream content + + // TODO is this needed? @Override - public InputStream getImageFULL(String pid) throws IOException { - return getDataStream(pid, FedoraUtils.IMG_FULL_STREAM); + public boolean isContentAccessible(String pid) throws IOException { + return true; } // TODO here we always use AkubraUtils.getStreamContent but we have also AkubraObject.AkubraDatastream for fetching stream content @@ -279,7 +575,9 @@ public InputStream getDataStream(String pid, String datastreamName) throws IOExc } } - private Document getStream(String pid, String streamName) throws IOException { + // XML data stream + @Override + public Document getStream(String pid, String streamName) throws IOException { DigitalObject object = manager.readObjectFromStorage(pid); if (object != null) { DatastreamVersionType stream = AkubraUtils.getLastStreamVersion(object, streamName); @@ -301,99 +599,14 @@ private Document getStream(String pid, String streamName) throws IOException { } - private Map createMap(String label) { - Map map = new HashMap(); - map.put("dsid", label); - map.put("label", label); - return map; - } - //-------------------------------------- - @Override - public Date getObjectLastmodifiedFlag(String pid) throws IOException { - DigitalObject object = manager.readObjectFromStorage(pid); - if (object != null) { - return AkubraUtils.getLastModified(object); - } - throw new IOException("Object not found: " + pid); - } - - - @Override - public boolean isObjectAvailable(String pid) throws IOException { - try { - return this.repository.objectExists(pid); - } catch (RepositoryException e) { - throw new IOException(e); - } - } - - @Override - public String getFedoraVersion() throws IOException { - return "Akubra"; - } + /* @Override public AkubraRepository getInternalAPI() throws RepositoryException { return this.repository; - } - - /* - @Override - public AkubraRepository getTransactionAwareInternalAPI() throws RepositoryException { - throw new RepositoryException("Transactions not supported in Akubra"); - } - - @Override - public Document getSmallThumbnailProfile(String pid) throws IOException { - throw new UnsupportedOperationException("unsupported"); - } - - @Override - public Document getImageFULLProfile(String pid) throws IOException { - throw new UnsupportedOperationException("unsupported"); - } - - @Override - public Document getStreamProfile(String pid, String stream) throws IOException { - throw new UnsupportedOperationException("unsupported"); - } - - @Override - public InputStream getFedoraDataStreamsList(String pid) throws IOException { - throw new UnsupportedOperationException("this is unsupported"); - } - - - @Override - public Document getDataStreamXmlAsDocument(String pid, String datastreamName) throws IOException { - throw new UnsupportedOperationException("this is unsupported"); - } - - @Override - public InputStream getDataStreamXml(String pid, String datastreamName) throws IOException { - throw new UnsupportedOperationException("this is unsupported"); - } - - - @Override - public Document getFedoraDataStreamsListAsDocument(String pid) throws IOException { - throw new UnsupportedOperationException("this is unsupported"); - } - - @Override - public Document getObjectProfile(String pid) throws IOException { - throw new UnsupportedOperationException("this is unsupported"); - } - - @Override - public void observeStreamHeaders(String pid, String datastreamName, StreamHeadersObserver streamObserver) - throws IOException { - throw new UnsupportedOperationException("unsupported operation"); - - } + }*/ - */ @Override public void shutdown() { @@ -410,18 +623,7 @@ private void reportAccess(String pid, String streamName) { } // -----------------------------------------------Former RespositoryAPIImpl - @Override - public void ingestObject(org.dom4j.Document foxmlDoc, String pid) throws RepositoryException, IOException { - DigitalObject digitalObject = foxmlDocToDigitalObject(foxmlDoc); - Lock writeLock = AkubraDOManager.getWriteLock(pid); - try { - akubraRepositoryImpl.ingestObject(digitalObject); - akubraRepositoryImpl.commitTransaction(); - } finally { - writeLock.unlock(); - } - } - +/* @Override public boolean objectExists(String pid) throws RepositoryException { Lock readLock = AkubraDOManager.getReadLock(pid); @@ -435,191 +637,19 @@ public boolean objectExists(String pid) throws RepositoryException { @Override public org.dom4j.Document getFoxml(String pid) throws RepositoryException, IOException { Lock readLock = AkubraDOManager.getReadLock(pid); - try { - RepositoryObject object = akubraRepositoryImpl.getObject(pid); - return Utils.inputstreamToDocument(object.getFoxml(), true); - } finally { - readLock.unlock(); - } - } - - @Override - public String getProperty(String pid, String propertyName) throws IOException, RepositoryException { - org.dom4j.Document objectFoxml = getFoxml(pid); - return objectFoxml == null ? null : extractProperty(objectFoxml, propertyName); - } - - @Override - public String getPropertyLabel(String pid) throws IOException, RepositoryException { - return getProperty(pid, "info:fedora/fedora-system:def/model#label"); - } - - @Override - public LocalDateTime getPropertyCreated(String pid) throws IOException, RepositoryException { - String propertyValue = getProperty(pid, "info:fedora/fedora-system:def/model#createdDate"); - if (propertyValue != null) { - try { - return LocalDateTime.parse(propertyValue, RepositoryApi.TIMESTAMP_FORMATTER); - } catch (DateTimeParseException e) { - System.out.println(String.format("cannot parse createdDate %s from object %s", propertyValue, pid)); - } - } - return null; - } - - @Override - public LocalDateTime getPropertyLastModified(String pid) throws IOException, RepositoryException { - String propertyValue = getProperty(pid, "info:fedora/fedora-system:def/view#lastModifiedDate"); - if (propertyValue != null) { - try { - return LocalDateTime.parse(propertyValue, RepositoryApi.TIMESTAMP_FORMATTER); - } catch (DateTimeParseException e) { - System.out.println(String.format("cannot parse lastModifiedDate %s from object %s", propertyValue, pid)); - } - } - return null; - } - - @Override - public List getDatastreamNames(String pid) throws RepositoryException, IOException, SolrServerException { - Lock readLock = AkubraDOManager.getReadLock(pid); - try { - RepositoryObject object = akubraRepositoryImpl.getObject(pid); - List streams = object.getStreams(); - return streams.stream().map(it -> { - try { - return it.getName(); - } catch (RepositoryException e) { - LOGGER.log(Level.SEVERE,e.getMessage(),e); - return null; - } - }).collect(Collectors.toList()); - } finally { - readLock.unlock(); - } - } - - @Override - public boolean datastreamExists(String pid, String dsId) throws RepositoryException, IOException { - Lock readLock = AkubraDOManager.getReadLock(pid); - try { - RepositoryObject object = akubraRepositoryImpl.getObject(pid); - return object == null ? false : object.streamExists(dsId); - } finally { - readLock.unlock(); - } - } - - @Override - public String getDatastreamMimetype(String pid, String dsId) throws RepositoryException, IOException { - Lock readLock = AkubraDOManager.getReadLock(pid); - try { - RepositoryObject object = akubraRepositoryImpl.getObject(pid); - if (object != null) { - RepositoryDatastream stream = object.getStream(dsId); - if (stream != null) { - return stream.getMimeType(); - } - } - return null; - } finally { - readLock.unlock(); - } - } - - @Override - public org.dom4j.Document getDatastreamXml(String pid, String dsId) throws RepositoryException, IOException { - Lock readLock = AkubraDOManager.getReadLock(pid); - try { - RepositoryObject object = akubraRepositoryImpl.getObject(pid); - if (object.streamExists(dsId)) { - org.dom4j.Document foxml = Utils.inputstreamToDocument(object.getFoxml(), true); - org.dom4j.Element dcEl = (org.dom4j.Element) Dom4jUtils.buildXpath(String.format("/foxml:digitalObject/foxml:datastream[@ID='%s']", dsId)).selectSingleNode(foxml); - org.dom4j.Element detached = (org.dom4j.Element) dcEl.detach(); - org.dom4j.Document result = DocumentHelper.createDocument(); - result.add(detached); - return result; - } else { - return null; - } - } finally { - readLock.unlock(); - } - } - - public String getTypeOfDatastream(String pid, String dsId) throws RepositoryException, IOException { - Lock readLock = AkubraDOManager.getReadLock(pid); - try { - RepositoryObject object = akubraRepositoryImpl.getObject(pid); - if (object.streamExists(dsId)) { - RepositoryDatastream stream = object.getStream(dsId); - return stream.getStreamType().name(); - } else { - return null; - } - } finally { - readLock.unlock(); - } - } - - @Override - public InputStream getLatestVersionOfDatastream(String pid, String dsId) throws RepositoryException, IOException { - Lock readLock = AkubraDOManager.getReadLock(pid); - try { - RepositoryObject object = akubraRepositoryImpl.getObject(pid); - if (object.streamExists(dsId)) { - RepositoryDatastream stream = object.getStream(dsId); - return stream.getContent(); - } else { - return null; - } - } finally { - readLock.unlock(); - } - } - - @Override - public org.dom4j.Document getLatestVersionOfInlineXmlDatastream(String pid, String dsId) throws RepositoryException, IOException { - InputStream is = getLatestVersionOfDatastream(pid, dsId); - return is == null ? null : Utils.inputstreamToDocument(is, true); - } - - @Override - public String getLatestVersionOfManagedTextDatastream(String pid, String dsId) throws RepositoryException, IOException { - InputStream is = getLatestVersionOfDatastream(pid, dsId); - return is == null ? null : Utils.inputstreamToString(is); - } - - @Override - public List getPidsOfAllObjects() throws RepositoryException, IOException, SolrServerException { - List pids = new ArrayList<>(); - //TODO: offset, limit - String query = "type:description"; - akubraRepositoryImpl.getProcessingIndexFeeder().iterateProcessingSortedByPid(query, (doc) -> { - Object fieldValue = doc.getFieldValue("source"); - if (fieldValue != null) { - String valueStr = fieldValue.toString(); - pids.add(valueStr); - } - }); - return pids; + try { + RepositoryObject object = akubraRepositoryImpl.getObject(pid); + return Utils.inputstreamToDocument(object.getFoxml(), true); + } finally { + readLock.unlock(); + } } +*/ - @Override - public List getPidsOfObjectsByModel(String model) throws RepositoryException, IOException, SolrServerException { - List pids = new ArrayList<>(); - //TODO: offset, limit - String query = String.format("type:description AND model:%s", "model\\:" + model); //prvni "model:" je filtr na solr pole, druhy "model:" je hodnota pole, coze uprime zbytecne - akubraRepositoryImpl.getProcessingIndexFeeder().iterateProcessingSortedByTitle(query, (doc) -> { - Object fieldValue = doc.getFieldValue("source"); - if (fieldValue != null) { - String valueStr = fieldValue.toString(); - pids.add(valueStr); - } - }); - return pids; - } + //------------------------------------------------------------- + ///////Processing index..//////////////////////////////////////////////////////////////////////////////////////// + // PI 1 @Override public Pair> getPidsOfObjectsByModel(String model, int rows, int pageIndex) throws RepositoryException, IOException, SolrServerException { String query = String.format("type:description AND model:%s", "model\\:" + model); //prvni "model:" je filtr na solr pole, druhy "model:" je hodnota pole, coze uprime zbytecne @@ -632,6 +662,7 @@ public Pair> getPidsOfObjectsByModel(String model, int rows, return new Pair<>(numberOfRecords, pids); } + // PI 2 //TODO : Should be replaced by pairs @Override public Pair> getPidsOfObjectsByModel(String model, String titlePrefix, int rows, int pageIndex) throws RepositoryException, IOException, SolrServerException { @@ -648,6 +679,7 @@ public Pair> getPidsOfObjectsByModel(String model, String tit return new Pair<>(numberOfRecords, pids); } + // PI 3 @Override public TitlePidPairs getPidsOfObjectsWithTitlesByModel(String model, boolean ascendingOrder, int offset, int limit) throws RepositoryException, IOException, SolrServerException { List> titlePidPairs = new ArrayList<>(); @@ -670,6 +702,7 @@ public TitlePidPairs getPidsOfObjectsWithTitlesByModel(String model, boolean asc return result; } + // PI 4 @Override public TitlePidPairs getPidsOfObjectsWithTitlesByModelWithCursor(String model, boolean ascendingOrder, String cursor, int limit) throws RepositoryException, IOException, SolrServerException { List> titlePidPairs = new ArrayList<>(); @@ -692,6 +725,8 @@ public TitlePidPairs getPidsOfObjectsWithTitlesByModelWithCursor(String model, b result.nextCursorMark = nextCursorMark; return result; } + + // PI 5 @Override public Map getDescription(String objectPid) throws RepositoryException, IOException, SolrServerException { Map description = new HashMap<>(); @@ -704,6 +739,7 @@ public Map getDescription(String objectPid) throws RepositoryExc return description; } + // PI 6 @Override public List getTripletTargets(String sourcePid, String relation) throws RepositoryException, IOException, SolrServerException { List pids = new ArrayList<>(); @@ -718,6 +754,7 @@ public List getTripletTargets(String sourcePid, String relation) throws return pids; } + // PI 7 @Override public List getTripletTargets(String sourcePid) throws RepositoryException, IOException, SolrServerException { List triplets = new ArrayList<>(); @@ -732,6 +769,7 @@ public List getTripletTargets(String sourcePid) throws RepositoryExcept return triplets; } + // PI 8 @Override public List getTripletSources(String relation, String targetPid) throws RepositoryException, IOException, SolrServerException { List pids = new ArrayList<>(); @@ -746,7 +784,7 @@ public List getTripletSources(String relation, String targetPid) throws return pids; } - + // PI 9 @Override public List getTripletSources(String targetPid) throws RepositoryException, IOException, SolrServerException { List triplets = new ArrayList<>(); @@ -761,309 +799,213 @@ public List getTripletSources(String targetPid) throws RepositoryExcept return triplets; } - - @Override - public void updateInlineXmlDatastream(String pid, String dsId, org.dom4j.Document streamDoc, String formatUri) throws RepositoryException, IOException { - Lock writeLock = AkubraDOManager.getWriteLock(pid); - try { - RepositoryObject object = akubraRepositoryImpl.getObject(pid); - - object.deleteStream(dsId); - object.createStream(dsId, "text/xml", new ByteArrayInputStream(streamDoc.asXML().getBytes(Charset.forName("UTF-8")))); - - } finally { - writeLock.unlock(); - } - } - - public void updateBinaryDatastream(String pid, String streamName, String mimeType, byte[] byteArray) throws RepositoryException { - Lock writeLock = AkubraDOManager.getWriteLock(pid); - try { - RepositoryObject object = akubraRepositoryImpl.getObject(pid); - if (object != null) { - if (object.streamExists(streamName)) { - object.deleteStream(streamName); - } - ByteArrayInputStream bos = new ByteArrayInputStream(byteArray); - object.createManagedStream(streamName, mimeType, bos); - } - } finally { - writeLock.unlock(); - } - } - - public void deleteDatastream(String pid, String streamName) throws RepositoryException { - Lock writeLock = AkubraDOManager.getWriteLock(pid); - try { - RepositoryObject object = akubraRepositoryImpl.getObject(pid); - if (object != null) { - if (object.streamExists(streamName)) { - object.deleteStream(streamName); - } - } - } finally { - writeLock.unlock(); - } - } - - + // PI 10 @Override - public void setDatastreamXml(String pid, String dsId, org.dom4j.Document ds) throws RepositoryException, IOException { - Lock writeLock = AkubraDOManager.getWriteLock(pid); - try { - org.dom4j.Document foxml = getFoxml(pid); - org.dom4j.Element originalDsEl = (org.dom4j.Element) Dom4jUtils.buildXpath(String.format("/foxml:digitalObject/foxml:datastream[@ID='%s']", dsId)).selectSingleNode(foxml); - if (originalDsEl != null) { - originalDsEl.detach(); - } - foxml.getRootElement().add(ds.getRootElement().detach()); - updateLastModifiedTimestamp(foxml); - DigitalObject updatedDigitalObject = foxmlDocToDigitalObject(foxml); - akubraRepositoryImpl.deleteObject(pid, false, false); - akubraRepositoryImpl.ingestObject(updatedDigitalObject); - akubraRepositoryImpl.commitTransaction(); - } finally { - writeLock.unlock(); - } - } - - private void updateLastModifiedTimestamp(org.dom4j.Document foxml) { - Attribute valueAttr = (Attribute) Dom4jUtils.buildXpath("/foxml:digitalObject/foxml:objectProperties/foxml:property[@NAME='info:fedora/fedora-system:def/view#lastModifiedDate']/@VALUE").selectSingleNode(foxml); - if (valueAttr != null) { - valueAttr.setValue(LocalDateTime.now().format(TIMESTAMP_FORMATTER)); - } else { - org.dom4j.Element objectProperties = (org.dom4j.Element) Dom4jUtils.buildXpath("/foxml:digitalObject/foxml:objectProperties").selectSingleNode(foxml); - org.dom4j.Element propertyLastModified = objectProperties.addElement(new QName("property", NS_FOXML)); - propertyLastModified.addAttribute("NAME", "info:fedora/fedora-system:def/view#lastModifiedDate"); - propertyLastModified.addAttribute("VALUE", LocalDateTime.now().format(RepositoryApi.TIMESTAMP_FORMATTER)); - } - } - - private void appendNewInlineXmlDatastreamVersion(org.dom4j.Document foxml, String dsId, org.dom4j.Document streamDoc, String formatUri) { - org.dom4j.Element datastreamEl = (org.dom4j.Element) Dom4jUtils.buildXpath(String.format("/foxml:digitalObject/foxml:datastream[@ID='%s']", dsId)).selectSingleNode(foxml); - if (datastreamEl != null) { - int latestDsIdVersion = extractLatestDsIdVersion(datastreamEl); - int newDsIdVesion = latestDsIdVersion + 1; - org.dom4j.Element dsVersionEl = datastreamEl.addElement("datastreamVersion", NAMESPACE_FOXML); - dsVersionEl.addAttribute("ID", dsId + "." + newDsIdVesion); - dsVersionEl.addAttribute("CREATED", LocalDateTime.now().format(TIMESTAMP_FORMATTER)); - dsVersionEl.addAttribute("MIMETYPE", "application/xml"); - if (formatUri != null) { - dsVersionEl.addAttribute("FORMAT_URI", formatUri); - } - org.dom4j.Element xmlContentEl = dsVersionEl.addElement("xmlContent", NAMESPACE_FOXML); - xmlContentEl.add(streamDoc.getRootElement().detach()); - } - } - - private int extractLatestDsIdVersion(org.dom4j.Element datastreamEl) { - List dsVersionEls = Dom4jUtils.buildXpath("foxml:datastreamVersion").selectNodes(datastreamEl); - int maxVersion = -1; - for (org.dom4j.Node node : dsVersionEls) { - org.dom4j.Element versionEl = (org.dom4j.Element) node; - String ID = Dom4jUtils.stringOrNullFromAttributeByName(versionEl, "ID"); - int versionNumber = Integer.valueOf(ID.split("\\.")[1]); - if (versionNumber > maxVersion) { - maxVersion = versionNumber; + public List getPidsOfObjectsByModel(String model) throws RepositoryException, IOException, SolrServerException { + List pids = new ArrayList<>(); + //TODO: offset, limit + String query = String.format("type:description AND model:%s", "model\\:" + model); //prvni "model:" je filtr na solr pole, druhy "model:" je hodnota pole, coze uprime zbytecne + akubraRepositoryImpl.getProcessingIndexFeeder().iterateProcessingSortedByTitle(query, (doc) -> { + Object fieldValue = doc.getFieldValue("source"); + if (fieldValue != null) { + String valueStr = fieldValue.toString(); + pids.add(valueStr); } - } - return maxVersion; - } - - @Override - public void deleteObject(String pid, boolean deleteDataOfManagedDatastreams) throws RepositoryException, IOException { - Lock writeLock = AkubraDOManager.getWriteLock(pid); - try { - akubraRepositoryImpl.deleteObject(pid, deleteDataOfManagedDatastreams, true); - akubraRepositoryImpl.commitTransaction(); - } finally { - writeLock.unlock(); - } - } - - - private DigitalObject foxmlDocToDigitalObject(org.dom4j.Document foxml) throws IOException { - try { - return (DigitalObject) digitalObjectUnmarshaller.unmarshal(new StringReader(foxml.asXML())); - } catch (JAXBException e) { - throw new IOException(e); - } - } - - private String extractProperty(org.dom4j.Document foxmlDoc, String name) { - org.dom4j.Node node = Dom4jUtils.buildXpath(String.format("/foxml:digitalObject/foxml:objectProperties/foxml:property[@NAME='%s']/@VALUE", name)).selectSingleNode(foxmlDoc); - return node == null ? null : Dom4jUtils.toStringOrNull(node); - } - - - //-----------------------Former KrameriusRepositoryAPIImpl----------------------------------- - @Override - public boolean isRelsExtAvailable(String pid) throws IOException, RepositoryException { - return repositoryApi.datastreamExists(pid, KnownDatastreams.RELS_EXT.toString()); - } - - @Override - public org.dom4j.Document getRelsExt(String pid, boolean namespaceAware) throws IOException, RepositoryException { - org.dom4j.Document doc = repositoryApi.getLatestVersionOfInlineXmlDatastream(pid, KnownDatastreams.RELS_EXT.toString()); - if (doc != null && !namespaceAware) { - doc.accept(new NamespaceRemovingVisitor(true, true)); - } - return doc; - } - - @Override - public boolean isModsAvailable(String pid) throws IOException, RepositoryException { - return repositoryApi.datastreamExists(pid, KnownDatastreams.BIBLIO_MODS.toString()); - } - - @Override - public org.dom4j.Document getMods(String pid, boolean namespaceAware) throws IOException, RepositoryException { - org.dom4j.Document doc = repositoryApi.getLatestVersionOfInlineXmlDatastream(pid, KnownDatastreams.BIBLIO_MODS.toString()); - if (doc != null && !namespaceAware) { - doc.accept(new NamespaceRemovingVisitor(true, true)); - } - return doc; - } - - @Override - public boolean isDublinCoreAvailable(String pid) throws IOException, RepositoryException { - return repositoryApi.datastreamExists(pid, KnownDatastreams.BIBLIO_DC.toString()); - } - - @Override - public org.dom4j.Document getDublinCore(String pid, boolean namespaceAware) throws IOException, RepositoryException { - org.dom4j.Document doc = repositoryApi.getLatestVersionOfInlineXmlDatastream(pid, KnownDatastreams.BIBLIO_DC.toString()); - if (doc != null && !namespaceAware) { - doc.accept(new NamespaceRemovingVisitor(true, true)); - } - return doc; - } - - @Override - public boolean isOcrTextAvailable(String pid) throws IOException, RepositoryException { - return repositoryApi.datastreamExists(pid, KnownDatastreams.OCR_TEXT.toString()); - } - - @Override - public String getOcrText(String pid) throws IOException, RepositoryException { - return repositoryApi.getLatestVersionOfManagedTextDatastream(pid, KnownDatastreams.OCR_TEXT.toString()); + }); + return pids; } - @Override - public boolean isOcrAltoAvailable(String pid) throws IOException, RepositoryException { - return repositoryApi.datastreamExists(pid, KnownDatastreams.OCR_ALTO.toString()); - } + // PI 11 + public List getPidsByCriteria(Map filters, String sortField, boolean ascending) + throws RepositoryException, IOException, SolrServerException { + List pids = new ArrayList<>(); + StringBuilder queryBuilder = new StringBuilder(); - @Override - public org.dom4j.Document getOcrAlto(String pid, boolean namespaceAware) throws IOException, RepositoryException { - org.dom4j.Document doc = repositoryApi.getLatestVersionOfInlineXmlDatastream(pid, KnownDatastreams.OCR_ALTO.toString()); - if (doc != null && !namespaceAware) { - doc.accept(new NamespaceRemovingVisitor(true, true)); + // Build the query from filters + filters.forEach((field, value) -> queryBuilder.append(field).append(":").append(value).append(" AND ")); + if (queryBuilder.length() > 0) { + queryBuilder.setLength(queryBuilder.length() - 5); // Remove trailing " AND " } - return doc; - } - @Override - public boolean isImgFullAvailable(String pid) throws IOException, RepositoryException { - return repositoryApi.datastreamExists(pid, KnownDatastreams.IMG_FULL.toString()); - } + // Sort query string + String sortClause = sortField != null ? String.format("sort:%s %s", sortField, ascending ? "ASC" : "DESC") : ""; - @Override - public String getImgFullMimetype(String pid) throws IOException, RepositoryException { - return repositoryApi.getDatastreamMimetype(pid, KnownDatastreams.IMG_FULL.toString()); - } + akubraRepositoryImpl.getProcessingIndexFeeder().iterateProcessingSortedByTitle( + queryBuilder.toString(), + (doc) -> { + Object fieldValue = doc.getFieldValue("source"); + if (fieldValue != null) { + String valueStr = fieldValue.toString(); + pids.add(valueStr); + } + } + ); - @Override - public InputStream getImgFull(String pid) throws IOException, RepositoryException { - this.accessLog.reportAccess(pid, KnownDatastreams.IMG_FULL.toString()); - return repositoryApi.getLatestVersionOfDatastream(pid, KnownDatastreams.IMG_FULL.toString()); + return pids; } + // PI 12 @Override - public boolean isImgThumbAvailable(String pid) throws IOException, RepositoryException { - return repositoryApi.datastreamExists(pid, KnownDatastreams.IMG_THUMB.toString()); + public List getPidsOfAllObjects() throws RepositoryException, IOException, SolrServerException { + List pids = new ArrayList<>(); + //TODO: offset, limit + String query = "type:description"; + akubraRepositoryImpl.getProcessingIndexFeeder().iterateProcessingSortedByPid(query, (doc) -> { + Object fieldValue = doc.getFieldValue("source"); + if (fieldValue != null) { + String valueStr = fieldValue.toString(); + pids.add(valueStr); + } + }); + return pids; } - @Override - public String getImgThumbMimetype(String pid) throws IOException, RepositoryException { - return repositoryApi.getDatastreamMimetype(pid, KnownDatastreams.IMG_THUMB.toString()); - } + //--- UPDATE ------------------------------------------------------------------------------------------------ @Override - public InputStream getImgThumb(String pid) throws IOException, RepositoryException { - return repositoryApi.getLatestVersionOfDatastream(pid, KnownDatastreams.IMG_THUMB.toString()); + public void ingestObject(org.dom4j.Document foxmlDoc, String pid) throws RepositoryException, IOException { + DigitalObject digitalObject = foxmlDocToDigitalObject(foxmlDoc); + Lock writeLock = AkubraDOManager.getWriteLock(pid); + try { + akubraRepositoryImpl.ingestObject(digitalObject); + akubraRepositoryImpl.commitTransaction(); + } finally { + writeLock.unlock(); + } } - @Override - public boolean isImgPreviewAvailable(String pid) throws IOException, RepositoryException { - return repositoryApi.datastreamExists(pid, KnownDatastreams.IMG_PREVIEW.toString()); - } @Override - public String getImgPreviewMimetype(String pid) throws IOException, RepositoryException { - return repositoryApi.getDatastreamMimetype(pid, KnownDatastreams.IMG_PREVIEW.toString()); - } + public void updateInlineXmlDatastream(String pid, String dsId, org.dom4j.Document streamDoc, String formatUri) throws RepositoryException, IOException { + Lock writeLock = AkubraDOManager.getWriteLock(pid); + try { + RepositoryObject object = akubraRepositoryImpl.getObject(pid); - @Override - public InputStream getImgPreview(String pid) throws IOException, RepositoryException { - this.accessLog.reportAccess(pid, KnownDatastreams.IMG_PREVIEW.toString()); - return repositoryApi.getLatestVersionOfDatastream(pid, KnownDatastreams.IMG_PREVIEW.toString()); - } + object.deleteStream(dsId); + object.createStream(dsId, "text/xml", new ByteArrayInputStream(streamDoc.asXML().getBytes(Charset.forName("UTF-8")))); - @Override - public boolean isAudioMp3Available(String pid) throws IOException, RepositoryException { - return repositoryApi.datastreamExists(pid, KnownDatastreams.AUDIO_MP3.toString()); + } finally { + writeLock.unlock(); + } } - @Override - public String getAudioMp3Mimetype(String pid) throws IOException, RepositoryException { - return repositoryApi.getDatastreamMimetype(pid, KnownDatastreams.AUDIO_MP3.toString()); + public void updateBinaryDatastream(String pid, String streamName, String mimeType, byte[] byteArray) throws RepositoryException { + Lock writeLock = AkubraDOManager.getWriteLock(pid); + try { + RepositoryObject object = akubraRepositoryImpl.getObject(pid); + if (object != null) { + if (object.streamExists(streamName)) { + object.deleteStream(streamName); + } + ByteArrayInputStream bos = new ByteArrayInputStream(byteArray); + object.createManagedStream(streamName, mimeType, bos); + } + } finally { + writeLock.unlock(); + } } - @Override - public InputStream getAudioMp3(String pid) throws IOException, RepositoryException { - this.accessLog.reportAccess(pid, KnownDatastreams.AUDIO_MP3.toString()); - return repositoryApi.getLatestVersionOfDatastream(pid, KnownDatastreams.AUDIO_MP3.toString()); + public void deleteDatastream(String pid, String streamName) throws RepositoryException { + Lock writeLock = AkubraDOManager.getWriteLock(pid); + try { + RepositoryObject object = akubraRepositoryImpl.getObject(pid); + if (object != null) { + if (object.streamExists(streamName)) { + object.deleteStream(streamName); + } + } + } finally { + writeLock.unlock(); + } } - @Override - public boolean isAudioOggAvailable(String pid) throws IOException, RepositoryException { - return repositoryApi.datastreamExists(pid, KnownDatastreams.AUDIO_OGG.toString()); - } @Override - public String getAudioOggMimetype(String pid) throws IOException, RepositoryException { - return repositoryApi.getDatastreamMimetype(pid, KnownDatastreams.AUDIO_OGG.toString()); + public void setDatastreamXml(String pid, String dsId, org.dom4j.Document ds) throws RepositoryException, IOException { + Lock writeLock = AkubraDOManager.getWriteLock(pid); + try { + org.dom4j.Document foxml = getFoxml(pid); + org.dom4j.Element originalDsEl = (org.dom4j.Element) Dom4jUtils.buildXpath(String.format("/foxml:digitalObject/foxml:datastream[@ID='%s']", dsId)).selectSingleNode(foxml); + if (originalDsEl != null) { + originalDsEl.detach(); + } + foxml.getRootElement().add(ds.getRootElement().detach()); + updateLastModifiedTimestamp(foxml); + DigitalObject updatedDigitalObject = foxmlDocToDigitalObject(foxml); + akubraRepositoryImpl.deleteObject(pid, false, false); + akubraRepositoryImpl.ingestObject(updatedDigitalObject); + akubraRepositoryImpl.commitTransaction(); + } finally { + writeLock.unlock(); + } } - @Override - public InputStream getAudioOgg(String pid) throws IOException, RepositoryException { - this.accessLog.reportAccess(pid, KnownDatastreams.AUDIO_OGG.toString()); - return repositoryApi.getLatestVersionOfDatastream(pid, KnownDatastreams.AUDIO_OGG.toString()); + private void updateLastModifiedTimestamp(org.dom4j.Document foxml) { + Attribute valueAttr = (Attribute) Dom4jUtils.buildXpath("/foxml:digitalObject/foxml:objectProperties/foxml:property[@NAME='info:fedora/fedora-system:def/view#lastModifiedDate']/@VALUE").selectSingleNode(foxml); + if (valueAttr != null) { + valueAttr.setValue(LocalDateTime.now().format(TIMESTAMP_FORMATTER)); + } else { + org.dom4j.Element objectProperties = (org.dom4j.Element) Dom4jUtils.buildXpath("/foxml:digitalObject/foxml:objectProperties").selectSingleNode(foxml); + org.dom4j.Element propertyLastModified = objectProperties.addElement(new QName("property", NS_FOXML)); + propertyLastModified.addAttribute("NAME", "info:fedora/fedora-system:def/view#lastModifiedDate"); + propertyLastModified.addAttribute("VALUE", LocalDateTime.now().format(RepositoryApi.TIMESTAMP_FORMATTER)); + } } - @Override - public boolean isAudioWavAvailable(String pid) throws IOException, RepositoryException { - return repositoryApi.datastreamExists(pid, KnownDatastreams.AUDIO_WAV.toString()); + private void appendNewInlineXmlDatastreamVersion(org.dom4j.Document foxml, String dsId, org.dom4j.Document streamDoc, String formatUri) { + org.dom4j.Element datastreamEl = (org.dom4j.Element) Dom4jUtils.buildXpath(String.format("/foxml:digitalObject/foxml:datastream[@ID='%s']", dsId)).selectSingleNode(foxml); + if (datastreamEl != null) { + int latestDsIdVersion = extractLatestDsIdVersion(datastreamEl); + int newDsIdVesion = latestDsIdVersion + 1; + org.dom4j.Element dsVersionEl = datastreamEl.addElement("datastreamVersion", NAMESPACE_FOXML); + dsVersionEl.addAttribute("ID", dsId + "." + newDsIdVesion); + dsVersionEl.addAttribute("CREATED", LocalDateTime.now().format(TIMESTAMP_FORMATTER)); + dsVersionEl.addAttribute("MIMETYPE", "application/xml"); + if (formatUri != null) { + dsVersionEl.addAttribute("FORMAT_URI", formatUri); + } + org.dom4j.Element xmlContentEl = dsVersionEl.addElement("xmlContent", NAMESPACE_FOXML); + xmlContentEl.add(streamDoc.getRootElement().detach()); + } } - @Override - public String getAudioWavMimetype(String pid) throws IOException, RepositoryException { - return repositoryApi.getDatastreamMimetype(pid, KnownDatastreams.AUDIO_WAV.toString()); + private int extractLatestDsIdVersion(org.dom4j.Element datastreamEl) { + List dsVersionEls = Dom4jUtils.buildXpath("foxml:datastreamVersion").selectNodes(datastreamEl); + int maxVersion = -1; + for (org.dom4j.Node node : dsVersionEls) { + org.dom4j.Element versionEl = (org.dom4j.Element) node; + String ID = Dom4jUtils.stringOrNullFromAttributeByName(versionEl, "ID"); + int versionNumber = Integer.valueOf(ID.split("\\.")[1]); + if (versionNumber > maxVersion) { + maxVersion = versionNumber; + } + } + return maxVersion; } @Override - public InputStream getAudioWav(String pid) throws IOException, RepositoryException { - return repositoryApi.getLatestVersionOfDatastream(pid, KnownDatastreams.AUDIO_WAV.toString()); + public void deleteObject(String pid, boolean deleteDataOfManagedDatastreams) throws RepositoryException, IOException { + Lock writeLock = AkubraDOManager.getWriteLock(pid); + try { + akubraRepositoryImpl.deleteObject(pid, deleteDataOfManagedDatastreams, true); + akubraRepositoryImpl.commitTransaction(); + } finally { + writeLock.unlock(); + } } - @Override - public String getModel(String objectPid) throws RepositoryException, IOException, SolrServerException { - Map description = repositoryApi.getDescription(objectPid); - String model = description.get("model"); - return model == null ? null : model.substring("model:".length()); + + private DigitalObject foxmlDocToDigitalObject(org.dom4j.Document foxml) throws IOException { + try { + return (DigitalObject) digitalObjectUnmarshaller.unmarshal(new StringReader(foxml.asXML())); + } catch (JAXBException e) { + throw new IOException(e); + } } + + //-----------------------Former KrameriusRepositoryAPIImpl----------------------------------- + @Override public Pair> getParents(String objectPid) throws RepositoryException, IOException, SolrServerException { List pseudoparentTriplets = repositoryApi.getTripletSources(objectPid); @@ -1139,4 +1081,91 @@ public boolean isStreamAvailable(String pid, String dsId) throws IOException, Re return exists; }*/ + /* + @Override + public Document getBiblioMods(String pid) throws IOException { + try { + return getStream(makeSureObjectPid(pid), FedoraUtils.BIBLIO_MODS_STREAM); + } catch (LexerException e) { + throw new IOException(e); + } + }*/ + + /* + @Override + public Document getRelsExt(String pid) throws IOException { + try { + // consider to change to metadata + return getStream(makeSureObjectPid(pid), FedoraUtils.RELS_EXT_STREAM); + } catch (LexerException e) { + throw new IOException(e); + } + }*/ + + /* + @Override + public Document getDC(String pid) throws IOException { + try { + return getStream(makeSureObjectPid(pid), FedoraUtils.DC_STREAM); + } catch (LexerException e) { + throw new IOException(e); + } + }*/ + /* + @Override + public String getFullThumbnailMimeType(String pid) throws IOException { + return getMimeTypeForStream(pid, FedoraUtils.IMG_PREVIEW_STREAM); + }*/ + + /* + @Override + public String getSmallThumbnailMimeType(String pid) throws IOException, XPathExpressionException { + return getMimeTypeForStream(pid, FedoraUtils.IMG_THUMB_STREAM); + }*/ + + /* + @Override + public InputStream getFullThumbnail(String pid) throws IOException { + try { + return getDataStream(makeSureObjectPid(pid), FedoraUtils.IMG_PREVIEW_STREAM); + } catch (LexerException e) { + throw new IOException(e); + } + }*/ + + /* + @Override + public InputStream getSmallThumbnail(String pid) throws IOException { + try { + return getDataStream(makeSureObjectPid(pid), FedoraUtils.IMG_THUMB_STREAM); + } catch (LexerException e) { + throw new IOException(e); + } + }*/ + + /* + @Override + public String getImageFULLMimeType(String pid) throws IOException, XPathExpressionException { + return getMimeTypeForStream(pid, FedoraUtils.IMG_FULL_STREAM); + }*/ + + /* + @Override + public InputStream getImageFULL(String pid) throws IOException { + return getDataStream(pid, FedoraUtils.IMG_FULL_STREAM); + }*/ + /* + @Override + public boolean isImageFULLAvailable(String pid) throws IOException { + return super.isImageFULLAvailable(pid); + }*/ + + /* + @Override + public boolean isFullthumbnailAvailable(String pid) throws IOException { + return this.isStreamAvailable(pid, FedoraUtils.IMG_PREVIEW_STREAM); + }*/ + + + } diff --git a/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/ResultMapper.java b/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/ResultMapper.java new file mode 100644 index 000000000..8552adc61 --- /dev/null +++ b/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/ResultMapper.java @@ -0,0 +1,12 @@ +package cz.incad.kramerius.fedora.impl.tmp; + +import org.apache.solr.common.SolrDocument; + +import java.util.List; + +@FunctionalInterface +public interface ResultMapper { + + T map(List documents, long totalRecords); + +} \ No newline at end of file diff --git a/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/SolrQueryParameters.java b/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/SolrQueryParameters.java new file mode 100644 index 000000000..6289e45d4 --- /dev/null +++ b/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/SolrQueryParameters.java @@ -0,0 +1,15 @@ +package cz.incad.kramerius.fedora.impl.tmp; + +import java.util.List; +import java.util.Map; + +public class SolrQueryParameters { + private final Map filters; + private final String sortField; + private final boolean ascending; + private final int rows; + private final int pageIndex; + private final List fieldsToFetch; + + // Constructor, getters, and builder pattern for flexibility +} diff --git a/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/SolrQueryService.java b/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/SolrQueryService.java new file mode 100644 index 000000000..100b8ba9e --- /dev/null +++ b/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/SolrQueryService.java @@ -0,0 +1,11 @@ +package cz.incad.kramerius.fedora.impl.tmp; + +import cz.incad.kramerius.fedora.om.repository.RepositoryException; + +import java.io.IOException; + +public interface SolrQueryService { + + T query(SolrQueryParameters params, ResultMapper mapper) throws RepositoryException, IOException, SolrServerException; + +} diff --git a/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/SolrQueryServiceImpl.java b/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/SolrQueryServiceImpl.java new file mode 100644 index 000000000..5225b9c37 --- /dev/null +++ b/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/SolrQueryServiceImpl.java @@ -0,0 +1,75 @@ +package cz.incad.kramerius.fedora.impl.tmp; + +import cz.incad.kramerius.fedora.om.repository.RepositoryException; +import cz.incad.kramerius.utils.java.Pair; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.common.SolrDocument; + +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; + +public class SolrQueryServiceImpl implements SolrQueryService { + + @Override + public T query(SolrQueryParameters params, ResultMapper mapper) + throws RepositoryException, IOException, SolrServerException { + + // Build query string from parameters + StringBuilder queryBuilder = new StringBuilder(); + params.getFilters().forEach((field, value) -> + queryBuilder.append(field).append(":").append(value).append(" AND ") + ); + if (queryBuilder.length() > 0) { + queryBuilder.setLength(queryBuilder.length() - 5); // Remove trailing " AND " + } + + // Fetch results from SOLR + org.apache.commons.lang3.tuple.Pair> cp = + akubraRepositoryImpl.getProcessingIndexFeeder().getPageSortedByTitle( + queryBuilder.toString(), + params.getRows(), + params.getPageIndex(), + params.getFieldsToFetch() + ); + + // Use the provided mapper to convert results + return mapper.map(cp.getRight(), cp.getLeft()); + } + + public static void main(String[] args) { + // Fetching a List of Strings: + SolrQueryParameters params = new SolrQueryParameters.Builder() + .filter("type", "description") + .filter("model", "desiredModel") + .sort("title", true) + .rows(10) + .pageIndex(0) + .fieldsToFetch(List.of("source")) + .build(); + + List pids = solrQueryService.query(params, (docs, total) -> + docs.stream() + .map(doc -> doc.getFieldValue("source").toString()) + .collect(Collectors.toList()) + ); + + // Fetching a Pair (Total Records, List of Strings): + Pair> result = solrQueryService.query(params, (docs, total) -> + new Pair<>(total, docs.stream() + .map(doc -> doc.getFieldValue("source").toString()) + .collect(Collectors.toList())) + ); + + // Fetching Custom Triplets: + List> triplets = solrQueryService.query(params, (docs, total) -> + docs.stream() + .map(doc -> new Triplet<>( + doc.getFieldValue("source").toString(), + doc.getFieldValue("title").toString(), + doc.getFieldValue("model").toString())) + .collect(Collectors.toList()) + ); + + } +} \ No newline at end of file diff --git a/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/TmpAbstractRepositoryAccess.java b/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/TmpAbstractRepositoryAccess.java new file mode 100644 index 000000000..66dd40409 --- /dev/null +++ b/shared/common/src/main/java/cz/incad/kramerius/fedora/impl/tmp/TmpAbstractRepositoryAccess.java @@ -0,0 +1,277 @@ +package cz.incad.kramerius.fedora.impl.tmp; + +import java.io.IOException; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.annotation.Nullable; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import com.google.inject.name.Named; +import com.qbizm.kramerius.imp.jaxb.DigitalObject; +import cz.incad.kramerius.fedora.RepositoryAccess; +import cz.incad.kramerius.fedora.om.repository.RepositoryException; +import cz.incad.kramerius.fedora.om.repository.impl.AkubraDOManager; +import cz.incad.kramerius.fedora.om.repository.impl.AkubraRepositoryImpl; +import cz.incad.kramerius.fedora.om.resourceindex.ProcessingIndexFeeder; +import cz.incad.kramerius.statistics.accesslogs.AggregatedAccessLogs; +import org.dom4j.Namespace; +import org.ehcache.CacheManager; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import com.google.inject.Inject; + +import cz.incad.kramerius.FedoraNamespaces; +import cz.incad.kramerius.ProcessSubtreeException; +import cz.incad.kramerius.TreeNodeProcessor; +import cz.incad.kramerius.statistics.StatisticsAccessLog; +import cz.incad.kramerius.fedora.utils.FedoraUtils; +import cz.incad.kramerius.utils.XMLUtils; +import cz.incad.kramerius.utils.conf.KConfiguration; +import cz.incad.kramerius.fedora.utils.pid.LexerException; + +public abstract class TmpAbstractRepositoryAccess implements RepositoryAccess { + //---------------------- + public static final Logger LOGGER = Logger.getLogger(RepositoryApi.class.getName()); + + private static final Namespace NS_FOXML = new Namespace("foxml", "info:fedora/fedora-system:def/foxml#"); + private final AkubraRepositoryImpl akubraRepositoryImpl; + private final Unmarshaller digitalObjectUnmarshaller; + //------------------------------------------------------------------------- + + public static final Logger LOGGER = Logger.getLogger(TmpAbstractRepositoryAccess.class.getName()); + protected XPathFactory xPathFactory; + protected KConfiguration configuration = KConfiguration.getInstance(); + + @Inject + public TmpAbstractRepositoryAccess(@Nullable StatisticsAccessLog accessLog) + throws IOException { + super(); + this.xPathFactory = XPathFactory.newInstance(); + } + + + + @Override + public String findFirstViewablePid(String pid) throws IOException { + final List foundPids = new ArrayList(); + try { + processSubtree(makeSureObjectPid(pid), new TreeNodeProcessor() { + boolean breakProcess = false; + int previousLevel = 0; + + @Override + public boolean breakProcessing(String pid, int level) { + return breakProcess; + } + + @Override + public boolean skipBranch(String pid, int level) { + return false; + } + + @Override + public void process(String pid, int level) throws ProcessSubtreeException { + try { + if (previousLevel < level || level == 0) { + if (TmpAbstractRepositoryAccess.this.isImageFULLAvailable(pid)) { + foundPids.add(pid); + breakProcess = true; + } + } else if (previousLevel > level) { + breakProcess = true; + } else if ((previousLevel == level) && (level != 0)) { + breakProcess = true; + } + previousLevel = level; + } catch (Exception e) { + throw new ProcessSubtreeException(e); + } + } + }); + } catch (ProcessSubtreeException e) { + throw new IOException(e); + } catch (LexerException e) { + throw new IOException(e); + } + + return foundPids.isEmpty() ? null : foundPids.get(0); + } + + @Override + public void processSubtree(String pid, TreeNodeProcessor processor) throws ProcessSubtreeException, IOException { + try { + pid = makeSureObjectPid(pid); + Document relsExt = null; + try { + // should be from + if (isStreamAvailable(pid, FedoraUtils.RELS_EXT_STREAM)) { + relsExt = getRelsExt(pid); + } else { + LOGGER.warning("could not read root RELS-EXT, skipping object (" + pid + ")"); + } + } catch (Exception ex) { + LOGGER.warning("could not read root RELS-EXT, skipping object (" + pid + "):" + ex); + } + if (!processor.skipBranch(pid, 0)) { + processSubtreeInternal(pid, relsExt, processor, 0, new Stack()); + } + } catch (LexerException e) { + LOGGER.warning("Error in pid: " + pid); + throw new ProcessSubtreeException(e); + } catch (XPathExpressionException e) { + throw new ProcessSubtreeException(e); + } + } + + + // TODO something more generic like getFieldFromStream + @Override + public String getDonator(String pid) throws IOException { + return getDonator(getRelsExt(pid)); + } + + // TODO something more generic like getFieldFromStream + @Override + public String getKrameriusModelName(String pid) throws IOException { + return getKrameriusModelName(getRelsExt(pid)); + } + + // TODO something more generic like getFieldFromStream + @Override + public List getPages(String pid, boolean deep) throws IOException { + Document relsExt = getRelsExt(pid); + return getPages(pid, relsExt.getDocumentElement()); + } + + + // TODO something more generic like getFieldFromStream + @Override + public String getFirstItemPid(String pid) throws IOException { + Document relsExt = getRelsExt(pid); + return getFirstItemPid(relsExt); + } + + // TODO something more generic like getFieldFromStream + @Override + public String getFirstVolumePid(String pid) throws IOException { + Document relsExt = getRelsExt(pid); + return getFirstVolumePid(relsExt); + } + + /* + @Override + public boolean isImageFULLAvailable(String pid) throws IOException { + try { + return isStreamAvailable(makeSureObjectPid(pid), FedoraUtils.IMG_FULL_STREAM); + } catch (LexerException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + throw new IOException(e); + } + }*/ + + @Override + public boolean getFirstViewablePath(List pids, List models) throws IOException { + try { + String pid = pids.get(pids.size() - 1); + pid = makeSureObjectPid(pid); + if (isImageFULLAvailable(pid)) { + return true; + } + Document relsExt = getRelsExt(pid); + Element descEl = XMLUtils.findElement(relsExt.getDocumentElement(), "Description", + FedoraNamespaces.RDF_NAMESPACE_URI); + List els = XMLUtils.getElements(descEl); + for (Element el : els) { + if (getTreePredicates().contains(el.getLocalName())) { + if (el.hasAttribute("rdf:resource")) { + pid = el.getAttributes().getNamedItem("rdf:resource").getNodeValue(); + pids.add(pid); + models.add(getKrameriusModelName(pid)); + if (getFirstViewablePath(pids, models)) { + return true; + } else { + pids.remove(pids.size() - 1); + models.remove(pids.size() - 1); + } + } + } + } + return false; + } catch (DOMException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + throw new IOException(e); + } catch (LexerException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + throw new IOException(e); + } + } + + /* + @Override + public List getModelsOfRel(Document relsExt) { + try { + throw new UnsupportedOperationException("still unsupported"); + // Element foundElement = + // XMLUtils.findElement(relsExt.getDocumentElement(), "hasModel", + // FedoraNamespaces.FEDORA_MODELS_URI); + // if (foundElement != null) { + // String sform = + // foundElement.getAttributeNS(FedoraNamespaces.RDF_NAMESPACE_URI, + // "resource"); + // PIDParser pidParser = new PIDParser(sform); + // pidParser.disseminationURI(); + // ArrayList model = + // RelsExtModelsMap.getModelsOfRelation(pidParser.getObjectId()); + // return model; + // } else { + // throw new IllegalArgumentException("cannot find model of "); + // } + } catch (DOMException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + throw new IllegalArgumentException(e); + } + }*/ + + /* + @Override + public List getModelsOfRel(String pid) throws IOException { + return getModelsOfRel(getRelsExt(pid)); + }*/ +// RepoApiImpl------------------------------------------------------------------------------------------- +@Inject +public RepositoryApiImpl(ProcessingIndexFeeder processingIndexFeeder, @Named("akubraCacheManager") CacheManager cacheManager) throws RepositoryException { + try { + AkubraDOManager akubraDOManager = new AkubraDOManager(cacheManager); + this.akubraRepositoryImpl = (AkubraRepositoryImpl) AkubraRepositoryImpl.build(processingIndexFeeder, akubraDOManager); + this.digitalObjectUnmarshaller = JAXBContext.newInstance(DigitalObject.class).createUnmarshaller(); + } catch (IOException e) { + throw new RepositoryException(e); + } catch (JAXBException e) { + throw new RepositoryException("Error initializing JAXB unmarshaller for " + DigitalObject.class.getName()); + } +} + + + //--------- KraRepositoryAPIIMPl + @javax.inject.Inject + private RepositoryApiImpl repositoryApi; + + @javax.inject.Inject + private AggregatedAccessLogs accessLog; + + + @Override + public RepositoryApi getLowLevelApi() { + return repositoryApi; + } + + +} diff --git a/shared/common/src/main/java/cz/incad/kramerius/fedora/utils/TmpUtils.java b/shared/common/src/main/java/cz/incad/kramerius/fedora/utils/TmpUtils.java new file mode 100644 index 000000000..0082b0aab --- /dev/null +++ b/shared/common/src/main/java/cz/incad/kramerius/fedora/utils/TmpUtils.java @@ -0,0 +1,239 @@ +package cz.incad.kramerius.fedora.utils; + +import cz.incad.kramerius.*; +import cz.incad.kramerius.fedora.utils.pid.LexerException; +import cz.incad.kramerius.fedora.utils.pid.PIDParser; +import cz.incad.kramerius.utils.XMLUtils; +import cz.incad.kramerius.utils.conf.KConfiguration; +import org.w3c.dom.*; + +import javax.xml.xpath.*; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Stack; +import java.util.logging.Level; + +public class TmpUtils { + + public static String getDonator(Document relsExt) { + try { + Element foundElement = XMLUtils.findElement(relsExt.getDocumentElement(), "hasDonator", + FedoraNamespaces.KRAMERIUS_URI); + if (foundElement != null) { + String sform = foundElement.getAttributeNS(FedoraNamespaces.RDF_NAMESPACE_URI, "resource"); + PIDParser pidParser = new PIDParser(sform); + pidParser.disseminationURI(); + return pidParser.getObjectId(); + } else { + return ""; + } + } catch (DOMException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + throw new IllegalArgumentException(e); + } catch (LexerException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + throw new IllegalArgumentException(e); + } + } + + protected void changeStack(TreeNodeProcessor processor, Stack pidStack) { + if (processor instanceof TreeNodeProcessStackAware) { + TreeNodeProcessStackAware stackAware = (TreeNodeProcessStackAware) processor; + stackAware.changeProcessingStack(pidStack); + } + } + + protected static boolean processSubtreeInternal(String pid, Document relsExt, TreeNodeProcessor processor, int level, + Stack pidStack) + throws XPathExpressionException, LexerException, IOException, ProcessSubtreeException { + processor.process(pid, level); + boolean breakProcessing = processor.breakProcessing(pid, level); + if (breakProcessing) { + return breakProcessing; + } + if (relsExt == null) { + return false; + } + XPathFactory factory = this.xPathFactory; + XPath xpath = factory.newXPath(); + xpath.setNamespaceContext(new FedoraNamespaceContext()); + XPathExpression expr = xpath.compile("/rdf:RDF/rdf:Description/*"); + NodeList nodes = (NodeList) expr.evaluate(relsExt, XPathConstants.NODESET); + + if (pidStack.contains(pid)) { + LOGGER.log(Level.WARNING, "Cyclic reference on " + pid); + return breakProcessing; + } + pidStack.push(pid); + changeStack(processor, pidStack); + for (int i = 0, ll = nodes.getLength(); i < ll; i++) { + Node node = nodes.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + Element iteratingElm = (Element) node; + String namespaceURI = iteratingElm.getNamespaceURI(); + if (namespaceURI != null && (namespaceURI.equals(FedoraNamespaces.ONTOLOGY_RELATIONSHIP_NAMESPACE_URI) + || namespaceURI.equals(FedoraNamespaces.RDF_NAMESPACE_URI))) { + String attVal = iteratingElm.getAttributeNS(FedoraNamespaces.RDF_NAMESPACE_URI, "resource"); + if (!attVal.trim().equals("")) { + PIDParser pidParser = new PIDParser(attVal); + pidParser.disseminationURI(); + String objectId = pidParser.getObjectPid(); + if (pidParser.getNamespaceId().equals("uuid")) { + if (!processor.skipBranch(objectId, level + 1)) { + Document iterationgRelsExt = null; + + try { + iterationgRelsExt = getRelsExt(objectId); + } catch (Exception ex) { + LOGGER.warning("could not read RELS-EXT, skipping branch [" + (level + 1) + + "] and pid (" + objectId + "):" + ex); + } + breakProcessing = processSubtreeInternal(pidParser.getObjectPid(), iterationgRelsExt, + processor, level + 1, pidStack); + + if (breakProcessing) { + break; + } + } else { + LOGGER.fine("skipping branch [" + (level + 1) + "] and pid (" + objectId + ")"); + } + } + } + + } + } + } + pidStack.pop(); + changeStack(processor, pidStack); + return breakProcessing; + } + + protected static String makeSureObjectPid(String pid) throws LexerException { + PIDParser pidParser = new PIDParser(pid); + pidParser.objectPid(); + String sureObjectPid = pidParser.isPagePid() ? pidParser.getParentObjectPid() : pidParser.getObjectPid(); + return sureObjectPid; + } + + + @Override + public List getPids(String pid) throws IOException { + final List retval = new ArrayList<>(); + try { + processSubtree(pid, new TreeNodeProcessor() { + @Override + public void process(String pid, int level) { + retval.add(pid); + } + + @Override + public boolean breakProcessing(String pid, int level) { + return false; + } + + @Override + public boolean skipBranch(String pid, int level) { + return false; + } + }); + } catch (ProcessSubtreeException e) { + throw new IOException(e); + } + return retval; + } + + @Override + public static String getKrameriusModelName(Document relsExt) throws IOException { + try { + //TODO: Duplicate code in RelsExt helper -> mn + Element foundElement = XMLUtils.findElement(relsExt.getDocumentElement(), "hasModel", FedoraNamespaces.FEDORA_MODELS_URI); + if (foundElement != null) { + String sform = foundElement.getAttributeNS(FedoraNamespaces.RDF_NAMESPACE_URI, "resource"); + PIDParser pidParser = new PIDParser(sform); + pidParser.disseminationURI(); + return pidParser.getObjectId(); + } else { + throw new IllegalArgumentException("cannot find model of given document"); + } + } catch (DOMException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + throw new IllegalArgumentException(e); + } catch (LexerException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + throw new IllegalArgumentException(e); + } + } + + @Override + public static String getFirstItemPid(Document relsExt) throws IOException { + try { + Element foundElement = XMLUtils.findElement(relsExt.getDocumentElement(), "hasItem", FedoraNamespaces.KRAMERIUS_URI); + if (foundElement != null) { + String sform = foundElement.getAttributeNS(FedoraNamespaces.RDF_NAMESPACE_URI, "resource"); + PIDParser pidParser = new PIDParser(sform); + pidParser.disseminationURI(); + String pidItem = "uuid:" + pidParser.getObjectId(); + return pidItem; + } else { + return ""; + } + } catch (DOMException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + throw new IllegalArgumentException(e); + } catch (LexerException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + throw new IllegalArgumentException(e); + } + } + + @Override + public static String getFirstVolumePid(Document relsExt) throws IOException { + + try { + Element foundElement = XMLUtils.findElement(relsExt.getDocumentElement(), "hasVolume", FedoraNamespaces.KRAMERIUS_URI); + if (foundElement != null) { + String sform = foundElement.getAttributeNS(FedoraNamespaces.RDF_NAMESPACE_URI, "resource"); + PIDParser pidParser = new PIDParser(sform); + pidParser.disseminationURI(); + String pidVolume = "uuid:" + pidParser.getObjectId(); + return pidVolume; + } else { + return ""; + } + } catch (DOMException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + throw new IllegalArgumentException(e); + } catch (LexerException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + throw new IllegalArgumentException(e); + } + } + + @Override + public static List getPages(String pid, Element rootElementOfRelsExt) throws IOException { + try { + ArrayList elms = new ArrayList(); + String xPathStr = "/RDF/Description/hasPage"; + XPath xpath = this.xPathFactory.newXPath(); + XPathExpression expr = xpath.compile(xPathStr); + NodeList nodes = (NodeList) expr.evaluate(rootElementOfRelsExt, XPathConstants.NODESET); + for (int i = 0, lastIndex = nodes.getLength() - 1; i <= lastIndex; i++) { + Element elm = (Element) nodes.item(i); + elms.add(elm); + } + return elms; + } catch (XPathExpressionException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + throw new IOException(e); + } + } + + protected List getTreePredicates() { + return Arrays.asList(KConfiguration.getInstance().getPropertyList("fedora.treePredicates")); + } + + + +}