Skip to content

Commit

Permalink
Refactor: RepositoryAccess facade
Browse files Browse the repository at this point in the history
  • Loading branch information
petrpodsed committed Dec 30, 2024
1 parent 0fe6b47 commit 9e33f7c
Show file tree
Hide file tree
Showing 5 changed files with 418 additions and 366 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package cz.incad.kramerius.fedora;

public interface ObjectAccess {
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

import com.qbizm.kramerius.imp.jaxb.DatastreamVersionType;
import com.qbizm.kramerius.imp.jaxb.DigitalObject;
import cz.incad.kramerius.FedoraNamespaces;
import cz.incad.kramerius.ProcessSubtreeException;
import cz.incad.kramerius.TreeNodeProcessor;
import cz.incad.kramerius.fedora.RepositoryAccess;
import cz.incad.kramerius.fedora.DatastreamAccess;
import cz.incad.kramerius.fedora.impl.tmp.TmpAbstractRepositoryAccess;
import cz.incad.kramerius.fedora.om.repository.RepositoryDatastream;
import cz.incad.kramerius.fedora.om.repository.RepositoryException;
import cz.incad.kramerius.fedora.om.repository.RepositoryObject;
Expand All @@ -12,13 +16,20 @@
import cz.incad.kramerius.fedora.utils.FedoraUtils;
import cz.incad.kramerius.fedora.utils.pid.LexerException;
import cz.incad.kramerius.repository.utils.NamespaceRemovingVisitor;
import cz.incad.kramerius.utils.XMLUtils;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.xpath.XPathExpressionException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.locks.Lock;
import java.util.logging.Level;

public class DatastreamAccessImpl implements DatastreamAccess {
@Override
Expand Down Expand Up @@ -300,6 +311,149 @@ public String getTypeOfDatastream(String pid, String dsId) throws RepositoryExce
}
}

@Override
public void updateRelsExt(String pid, org.dom4j.Document relsExtDoc) throws IOException, RepositoryException {
updateInlineXmlDatastream(pid, RepositoryAccess.KnownDatastreams.RELS_EXT.toString(), relsExtDoc, RepositoryAccess.KnownXmlFormatUris.RELS_EXT);
}
@Override
public void updateMods(String pid, org.dom4j.Document modsDoc) throws IOException, RepositoryException {
updateInlineXmlDatastream(pid, RepositoryAccess.KnownDatastreams.BIBLIO_MODS.toString(), modsDoc, RepositoryAccess.KnownXmlFormatUris.BIBLIO_MODS);
}
@Override
public void updateDublinCore(String pid, org.dom4j.Document dcDoc) throws IOException, RepositoryException {
updateInlineXmlDatastream(pid, RepositoryAccess.KnownDatastreams.BIBLIO_DC.toString(), dcDoc, RepositoryAccess.KnownXmlFormatUris.BIBLIO_DC);
}

// relsExt
@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 String findFirstViewablePid(String pid) throws IOException {
final List<String> foundPids = new ArrayList<String>();
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<String>());
}
} catch (LexerException e) {
LOGGER.warning("Error in pid: " + pid);
throw new ProcessSubtreeException(e);
} catch (XPathExpressionException e) {
throw new ProcessSubtreeException(e);
}
}
@Override
public List<Element> getPages(String pid, boolean deep) throws IOException {
Document relsExt = getRelsExt(pid);
return getPages(pid, relsExt.getDocumentElement());
}
@Override
public String getFirstItemPid(String pid) throws IOException {
Document relsExt = getRelsExt(pid);
return getFirstItemPid(relsExt);
}
@Override
public String getFirstVolumePid(String pid) throws IOException {
Document relsExt = getRelsExt(pid);
return getFirstVolumePid(relsExt);
}
@Override
public boolean getFirstViewablePath(List<String> pids, List<String> 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<Element> 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);
}
}

/*
// TODO current stream access methods, just one method rendering 2 content types; also we can add new par dsId and if null the whole foxml will be returned
Expand All @@ -322,30 +476,6 @@ public org.dom4j.Document getDatastreamXml(String pid, String dsId) throws Repos
readLock.unlock();
}
}
@Override
public InputStream getFoxml(String pid, boolean archive) throws IOException {
try {
if (archive){
DigitalObject obj = manager.readObjectCloneFromStorage(pid);
manager.resolveArchivedDatastreams(obj);
return this.manager.marshallObject(obj);
}else {
return this.manager.retrieveObject(pid);
}
} catch (Exception e) {
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();
}
}
// <--- AkubraObject.getStream.getContent (6x)
public InputStream getLatestVersionOfDatastream(String pid, String dsId) throws RepositoryException, IOException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package cz.incad.kramerius.fedora.impl;

import com.qbizm.kramerius.imp.jaxb.DigitalObject;
import cz.incad.kramerius.fedora.ObjectAccess;
import cz.incad.kramerius.fedora.om.repository.RepositoryException;
import cz.incad.kramerius.fedora.utils.AkubraUtils;
import cz.incad.kramerius.utils.Dom4jUtils;
import org.apache.solr.client.solrj.SolrServerException;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeParseException;
import java.util.Date;
import java.util.Map;

public class ObjectAccessImpl implements ObjectAccess {

//-------- get object property
@Override
public String getProperty(String pid, String propertyName) throws IOException, RepositoryException {
org.dom4j.Document objectFoxml = getFoxml(pid);
return objectFoxml == null ? null : extractProperty(objectFoxml, propertyName);
}
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);
}
@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 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 String getModel(String objectPid) throws RepositoryException, IOException, SolrServerException {
Map<String, String> description = repositoryApi.getDescription(objectPid);
String model = description.get("model");
return model == null ? null : model.substring("model:".length());
}
/*
@Override
public InputStream getFoxml(String pid, boolean archive) throws IOException {
try {
if (archive){
DigitalObject obj = manager.readObjectCloneFromStorage(pid);
manager.resolveArchivedDatastreams(obj);
return this.manager.marshallObject(obj);
}else {
return this.manager.retrieveObject(pid);
}
} catch (Exception e) {
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();
}
}
@Override
public boolean objectExists(String pid) throws RepositoryException {
Lock readLock = AkubraDOManager.getReadLock(pid);
try {
return akubraRepositoryImpl.objectExists(pid);
} finally {
readLock.unlock();
}
}
@Override
public boolean isPidAvailable(String pid) throws IOException, RepositoryException {
boolean exists = this.repositoryApi.objectExists(pid);
return exists;
}
*/

}
Loading

0 comments on commit 9e33f7c

Please sign in to comment.