Java tutorial
/* * $Id$ * $Revision$ * $Date$ * $Author$ * * The DOMS project. * Copyright (C) 2007-2010 The State and University Library * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package dk.statsbiblioteket.doms.central; import com.sun.xml.ws.developer.servlet.HttpSessionScope; import dk.statsbiblioteket.doms.central.connectors.BackendInvalidCredsException; import dk.statsbiblioteket.doms.central.connectors.BackendInvalidResourceException; import dk.statsbiblioteket.doms.central.connectors.BackendMethodFailedException; import dk.statsbiblioteket.doms.central.connectors.EnhancedFedora; import dk.statsbiblioteket.doms.central.connectors.EnhancedFedoraImpl; import dk.statsbiblioteket.doms.central.connectors.authchecker.AuthChecker; import dk.statsbiblioteket.doms.central.connectors.fedora.linkpatterns.LinkPattern; import dk.statsbiblioteket.doms.central.connectors.fedora.methods.generated.Parameter; import dk.statsbiblioteket.doms.central.connectors.fedora.pidGenerator.PIDGeneratorException; import dk.statsbiblioteket.doms.central.connectors.fedora.structures.FedoraRelation; import dk.statsbiblioteket.doms.central.connectors.updatetracker.UpdateTracker; import dk.statsbiblioteket.doms.central.connectors.updatetracker.UpdateTrackerRecord; import dk.statsbiblioteket.doms.central.summasearch.SearchWS; import dk.statsbiblioteket.doms.central.summasearch.SearchWSService; import dk.statsbiblioteket.sbutil.webservices.authentication.Credentials; import dk.statsbiblioteket.sbutil.webservices.configuration.ConfigCollection; import dk.statsbiblioteket.util.xml.DOM; import net.sf.json.JSONObject; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.annotation.PostConstruct; import javax.annotation.Resource; import javax.jws.WebParam; import javax.jws.WebService; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.xml.bind.DatatypeConverter; import javax.xml.bind.JAXBException; import javax.xml.namespace.QName; import javax.xml.ws.WebServiceContext; import javax.xml.ws.handler.MessageContext; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import java.lang.String; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by IntelliJ IDEA. User: abr Date: Aug 18, 2010 Time: 2:01:51 PM To change this template use File | Settings | * File Templates. */ @Path("/") @WebService(endpointInterface = "dk.statsbiblioteket.doms.central.CentralWebservice") @HttpSessionScope public class CentralWebserviceImpl implements CentralWebservice { @Resource WebServiceContext context; @Context HttpServletRequest restRequest; private static Log log = LogFactory.getLog(CentralWebserviceImpl.class); private static Lock lock = new Lock(); private UpdateTracker updateTracker; private EnhancedFedora fedora; private AuthChecker authChecker; /** * Initialise the context. This retrieves the credentials from the request object. It then creates the fedora and * summaSearch object. * This method is annotated with @PostConstruct, so it will automatically be run by the SOAP framework before any of * the methods have been called.This is nessesary,as the request object have not been populated at the constructor time, and * we can thus not read the credentials. * @throws MalformedURLException If one of the config urls could not be parsed * @throws PIDGeneratorException If the pidgenerator client could not be instantiaed * @throws JAXBException If some jaxb classes could not be parsed */ @PostConstruct protected void initialise() throws MalformedURLException, PIDGeneratorException, JAXBException { Credentials creds = getCredentials(); fedora = getEnhancedFedora(creds); updateTracker = getUpdateTracker(creds); authChecker = getAuthChecker(); } /** * Initialise the AuthChecker connector. Reads the property dk.statsbiblioteket.doms.central.authCheckerLocation to get the location * @return * @throws MalformedURLException */ protected AuthChecker getAuthChecker() throws MalformedURLException { String authCheckerLocation = ConfigCollection.getProperties() .getProperty("dk.statsbiblioteket.doms.central.authCheckerLocation"); return new AuthChecker(authCheckerLocation); } /** * Create a new updatetracker client. Reads the property dk.statsbiblioteket.doms.central.updateTrackerLocation to get the location * @param creds the user creds * @return * @throws MalformedURLException */ protected UpdateTracker getUpdateTracker(Credentials creds) throws MalformedURLException { String updateTrackerLocation = ConfigCollection.getProperties() .getProperty("dk.statsbiblioteket.doms.central.updateTrackerLocation"); return new UpdateTracker(creds, updateTrackerLocation); } /** * Create a new summa search client. Reads the property dk.statsbiblioteket.doms.central.summaWSDL to get the location * @return * @throws MalformedURLException */ protected SearchWS getSearchWSService() throws MalformedURLException { String summaLocation = ConfigCollection.getProperties() .getProperty("dk.statsbiblioteket.doms.central.summaWSDL"); return new SearchWSService(new java.net.URL(summaLocation), new QName("http://statsbiblioteket.dk/summa/search", "SearchWSService")).getSearchWS(); } /** * Create a new instance of enhancedFedora from the creds. Reads the properties * dk.statsbiblioteket.doms.central.fedoraLocation and * dk.statsbiblioteket.doms.ecm.pidgenerator.client.wsdllocation * @param creds the user credentials * @return * @throws MalformedURLException * @throws PIDGeneratorException * @throws JAXBException */ protected EnhancedFedora getEnhancedFedora(Credentials creds) throws MalformedURLException, PIDGeneratorException, JAXBException { String fedoraLocation = ConfigCollection.getProperties() .getProperty("dk.statsbiblioteket.doms.central.fedoraLocation"); String thisLocation = getServletRequest().getRequestURL().toString(); String pidgeneratorLocation = ConfigCollection.getProperties() .getProperty("dk.statsbiblioteket.doms.ecm.pidgenerator.client.wsdllocation"); return new EnhancedFedoraImpl(creds, fedoraLocation, pidgeneratorLocation, thisLocation); } // TODO: rename pid to templatePid @Override public String newObject(@WebParam(name = "pid", targetNamespace = "") String pid, @WebParam(name = "oldID", targetNamespace = "") List<String> oldID, @WebParam(name = "comment", targetNamespace = "") String comment) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { long token = lock.getReadAndWritePerm(); try { log.trace("Entering newObject with params pid=" + pid + " and oldIDs=" + oldID.toString()); return fedora.cloneTemplate(pid, oldID, comment); } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } finally { lock.releaseReadAndWritePerm(token); } } @Override public ObjectProfile getObjectProfile(@WebParam(name = "pid", targetNamespace = "") String pid) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { try { log.trace("Entering getObjectProfile with params pid='" + pid + "'"); dk.statsbiblioteket.doms.central.connectors.fedora.structures.ObjectProfile fprofile = fedora .getObjectProfile(pid, null); ObjectProfile wprofile = new ObjectProfile(); wprofile.setTitle(fprofile.getLabel()); wprofile.setPid(fprofile.getPid()); wprofile.setState(fprofile.getState()); wprofile.setCreatedDate(fprofile.getObjectCreatedDate().getTime()); wprofile.setModifiedDate(fprofile.getObjectLastModifiedDate().getTime()); wprofile.getContentmodels().addAll(fprofile.getContentModels()); switch (fprofile.getType()) { case CONTENT_MODEL: wprofile.setType("ContentModel"); break; case DATA_OBJECT: wprofile.setType("DataObject"); break; case TEMPLATE: wprofile.setType("TemplateObject"); break; case COLLECTION: wprofile.setType("CollectionObject"); break; case FILE: wprofile.setType("FileObject"); break; } //Datastreams List<DatastreamProfile> datastreams = wprofile.getDatastreams(); for (dk.statsbiblioteket.doms.central.connectors.fedora.structures.DatastreamProfile datastreamProfile : fprofile .getDatastreams()) { DatastreamProfile wdprofile = new DatastreamProfile(); wdprofile.setId(datastreamProfile.getID()); wdprofile.setLabel(datastreamProfile.getLabel()); wdprofile.setChecksum(new Checksum()); wdprofile.getChecksum().setType(datastreamProfile.getChecksumType()); wdprofile.getChecksum().setValue(datastreamProfile.getChecksum()); wdprofile.setMimeType(datastreamProfile.getMimeType()); wdprofile.setFormatUri(datastreamProfile.getFormatURI()); wdprofile.setInternal(datastreamProfile.isInternal()); if (!wdprofile.isInternal()) { wdprofile.setUrl(datastreamProfile.getUrl()); } datastreams.add(wdprofile); } //Relations List<Relation> wrelations = wprofile.getRelations(); wrelations.addAll(convertRelations(fprofile.getRelations())); return wprofile; } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } @Override public void setObjectLabel(@WebParam(name = "pid", targetNamespace = "") String pid, @WebParam(name = "name", targetNamespace = "") String name, @WebParam(name = "comment", targetNamespace = "") String comment) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { long token = lock.getReadAndWritePerm(); try { log.trace("Entering setObjectLabel with params pid=" + pid + " and name=" + name); fedora.modifyObjectLabel(pid, name, comment); } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } finally { lock.releaseReadAndWritePerm(token); } } @Override public void deleteObject(@WebParam(name = "pids", targetNamespace = "") List<String> pids, @WebParam(name = "comment", targetNamespace = "") String comment) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { long token = lock.getReadAndWritePerm(); try { log.trace("Entering deleteObject with params pid=" + pids); for (String pid : pids) { fedora.modifyObjectState(pid, fedora.STATE_DELETED, comment); } } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } finally { lock.releaseReadAndWritePerm(token); } } @Override public void markPublishedObject(@WebParam(name = "pids", targetNamespace = "") List<String> pids, @WebParam(name = "comment", targetNamespace = "") String comment) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { long token = lock.getReadAndWritePerm(); List<String> activated = new ArrayList<String>(); try { log.trace("Entering markPublishedObject with params pids=" + pids); for (String pid : pids) { fedora.modifyObjectState(pid, fedora.STATE_ACTIVE, comment); activated.add(pid); } } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); //rollback comment = comment + ": Publishing failed, marking back to InProgress"; markInProgressObject(activated, comment); throw new MethodFailedException("Method failed to execute: " + e.getMessage(), "Method failed to execute: " + e.getMessage(), e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); comment = comment + ": Publishing failed, marking back to InProgress"; markInProgressObject(activated, comment); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); comment = comment + ": Publishing failed, marking back to InProgress"; markInProgressObject(activated, comment); throw new MethodFailedException("Server error", "Server error", e); } finally { lock.releaseReadAndWritePerm(token); } } @Override public void markInProgressObject(@WebParam(name = "pids", targetNamespace = "") List<String> pids, @WebParam(name = "comment", targetNamespace = "") String comment) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { long token = lock.getReadAndWritePerm(); try { log.trace("Entering markInProgressObject with params pids=" + pids); for (String pid : pids) { fedora.modifyObjectState(pid, fedora.STATE_INACTIVE, comment); } } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } finally { lock.releaseReadAndWritePerm(token); } } @Override public void modifyDatastream(@WebParam(name = "pid", targetNamespace = "") String pid, @WebParam(name = "datastream", targetNamespace = "") String datastream, @WebParam(name = "contents", targetNamespace = "") String contents, @WebParam(name = "comment", targetNamespace = "") String comment) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { long token = lock.getReadAndWritePerm(); try { log.trace("Entering modifyDatastream with params pid=" + pid + " and datastream=" + datastream + " and contents=" + contents); fedora.modifyDatastreamByValue(pid, datastream, null, null, contents.getBytes(), null, "text/xml", comment, null); } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } finally { lock.releaseReadAndWritePerm(token); } } @Override @GET @Path("objects/{pid}/datastreams/{datastream}") @Produces("text/xml") public String getDatastreamContents(@PathParam("pid") @WebParam(name = "pid", targetNamespace = "") String pid, @PathParam("datastream") @WebParam(name = "datastream", targetNamespace = "") String datastream) throws MethodFailedException, InvalidCredentialsException, InvalidResourceException { try { log.trace("Entering getDatastreamContents with params pid=" + pid + " and datastream=" + datastream); return fedora.getXMLDatastreamContents(pid, datastream, null); } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } @Override public void addFileFromPermanentURL(@WebParam(name = "pid", targetNamespace = "") String pid, @WebParam(name = "filename", targetNamespace = "") String filename, @WebParam(name = "md5sum", targetNamespace = "") String md5Sum, @WebParam(name = "permanentURL", targetNamespace = "") String permanentURL, @WebParam(name = "formatURI", targetNamespace = "") String formatURI, @WebParam(name = "comment", targetNamespace = "") String comment) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { long token = lock.getReadAndWritePerm(); try { log.trace("Entering addFileFromPermamentURL with params pid=" + pid + " and filename=" + filename + " and md5sum=" + md5Sum + " and permanentURL=" + permanentURL + " and formatURI=" + formatURI); String existingObject = getFileObjectWithURL(permanentURL); if (existingObject != null) { log.warn("Attempt to add a permament url that already exists" + "in DOMS"); throw new MethodFailedException( "This permanent url has already " + "been added to the object '" + existingObject + "'", "This permanent url has already " + "been added to the object '" + existingObject + "'"); } fedora.addExternalDatastream(pid, "CONTENTS", filename, permanentURL, formatURI, "application/octet-stream", null, comment); setObjectLabel(pid, permanentURL, comment); } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } finally { lock.releaseReadAndWritePerm(token); } } public String getFileObjectWithURL(@WebParam(name = "URL", targetNamespace = "") String url) throws MethodFailedException, InvalidCredentialsException, InvalidResourceException { try { log.trace("Entering getFileObjectWithURL with param url=" + url); List<String> objects = fedora.listObjectsWithThisLabel(url); if (objects != null && !objects.isEmpty()) { return objects.get(0); } else { return null; } } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } @Override public void addRelation(@WebParam(name = "pid", targetNamespace = "") String pid, @WebParam(name = "relation", targetNamespace = "") Relation relation, @WebParam(name = "comment", targetNamespace = "") String comment) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { long token = lock.getReadAndWritePerm(); try { log.trace("Entering addRelation with params pid=" + pid + " and subject=" + relation.getSubject() + " and predicate=" + relation.getPredicate() + " and object=" + relation.getObject()); fedora.addRelation(pid, relation.subject, relation.predicate, relation.object, relation.literal, comment); } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } finally { lock.releaseReadAndWritePerm(token); } } @Override public List<Relation> getRelations(@WebParam(name = "pid", targetNamespace = "") String pid) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { log.trace("Entering getRelations with params pid='" + pid + "'"); return getNamedRelations(pid, null); } @Override public List<Relation> getNamedRelations(@WebParam(name = "pid", targetNamespace = "") String pid, @WebParam(name = "predicate", targetNamespace = "") String predicate) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { try { log.trace("Entering getNamedRelations with params pid='" + pid + "'"); List<FedoraRelation> fedorarels = fedora.getNamedRelations(pid, predicate, null); return convertRelations(fedorarels); } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } @Override public List<Relation> getInverseRelations(@WebParam(name = "pid", targetNamespace = "") String pid) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { try { log.trace("Entering getInverseRelations with params pid='" + pid + "'"); List<FedoraRelation> fedorarels = fedora.getInverseRelations(pid, null); return convertRelations(fedorarels); } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } @Override public List<Relation> getInverseRelationsWithPredicate(@WebParam(name = "pid", targetNamespace = "") String pid, @WebParam(name = "predicate", targetNamespace = "") String predicate) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { try { log.trace("Entering getInverseRelations with params pid='" + pid + "'"); List<FedoraRelation> fedorarels = fedora.getInverseRelations(pid, predicate); return convertRelations(fedorarels); } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } @Override public void deleteRelation(@WebParam(name = "pid", targetNamespace = "") String pid, @WebParam(name = "relation", targetNamespace = "") Relation relation, @WebParam(name = "comment", targetNamespace = "") String comment) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { long token = lock.getReadAndWritePerm(); try { log.trace("Entering deleteRelation with params pid=" + pid + " and subject=" + relation.subject + " and predicate=" + relation.predicate + " and object=" + relation.object); fedora.deleteRelation(pid, relation.subject, relation.predicate, relation.object, relation.literal, comment); } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } finally { lock.releaseReadAndWritePerm(token); } } public ViewBundle getViewBundle(@WebParam(name = "pid", targetNamespace = "") String pid, @WebParam(name = "name", targetNamespace = "") String viewAngle) throws InvalidCredentialsException, MethodFailedException, InvalidResourceException { return getViewBundleFromSpecificTime(pid, viewAngle, -1); } @Override public ViewBundle getViewBundleFromSpecificTime(@WebParam(name = "pid", targetNamespace = "") String pid, @WebParam(name = "ViewAngle", targetNamespace = "") String viewAngle, @WebParam(name = "asOfTime", targetNamespace = "") long asOfTime) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { log.trace("Entering getViewBundle with params pid=" + pid + " and viewAngle=" + viewAngle + " and timestamp=" + asOfTime); /* * Pseudo kode here * We need to figure two things out * the bundle * the type * ECM generates the bundle * The type is the entry content model of the origin pid * */ try { /* List<String> types = ecm.getEntryContentModelsForObject(pid, viewAngle); if (types.isEmpty()) { throw new BackendInvalidResourceException("Pid '"+pid+"'is not an entry object for angle '"+viewAngle+"'"); } */ java.lang.Long timestamp = null; if (asOfTime >= 0) { timestamp = asOfTime; } Document bundleContents = fedora.createBundle(pid, viewAngle, timestamp); String bundleContentsString = DOM.domToString(bundleContents); ViewBundle viewBundle = new ViewBundle(); viewBundle.setId(pid); viewBundle.setContents(bundleContentsString); return viewBundle; } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } public List<RecordDescription> getIDsModified(@WebParam(name = "since", targetNamespace = "") long since, @WebParam(name = "collectionPid", targetNamespace = "") String collectionPid, @WebParam(name = "viewAngle", targetNamespace = "") String viewAngle, @WebParam(name = "state", targetNamespace = "") String state, @WebParam(name = "offset", targetNamespace = "") Integer offset, @WebParam(name = "limit", targetNamespace = "") Integer limit) throws InvalidCredentialsException, MethodFailedException { try { logEntering("getIDsModified", since + "", collectionPid, viewAngle, state, offset + "", limit + ""); if (state == null || state.isEmpty()) { state = "Published"; } List<UpdateTrackerRecord> modifieds = updateTracker.listObjectsChangedSince(collectionPid, viewAngle, since, state, offset, limit); return transform(modifieds); } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } public long getLatestModified(@WebParam(name = "collectionPid", targetNamespace = "") String collectionPid, @WebParam(name = "viewAngle", targetNamespace = "") String viewAngle, @WebParam(name = "state", targetNamespace = "") String state) throws InvalidCredentialsException, MethodFailedException { try { logEntering("getLatestModified", collectionPid, viewAngle, state); return updateTracker.getLatestModification(collectionPid, viewAngle, state); } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } @Override public List<String> findObjectFromDCIdentifier(@WebParam(name = "string", targetNamespace = "") String string) throws InvalidCredentialsException, MethodFailedException { try { log.trace("Entering findObjectFromDCIdentifier with param string=" + string); List<String> objects = fedora.findObjectFromDCIdentifier(string); return objects; /* if (objects != null && !objects.isEmpty()) { return objects.get(0); } else { return null; } */ } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } @Override public SearchResultList findObjects(@WebParam(name = "query", targetNamespace = "") String query, @WebParam(name = "offset", targetNamespace = "") int offset, @WebParam(name = "pageSize", targetNamespace = "") int pageSize) throws MethodFailedException { try { log.trace("Entering findObjects with param query=" + query + ", offset=" + offset + ", pageSize=" + pageSize); JSONObject jsonQuery = new JSONObject(); jsonQuery.put("search.document.resultfields", "recordID, domsshortrecord"); jsonQuery.put("search.document.query", query); jsonQuery.put("search.document.startindex", offset); jsonQuery.put("search.document.maxrecords", pageSize); SearchWS summaSearch = getSearchWSService(); String searchResultString = summaSearch.directJSON(jsonQuery.toString()); Document searchResultDOM = DOM.stringToDOM(searchResultString); XPath xPath = XPathFactory.newInstance().newXPath(); NodeList nodeList = (NodeList) xPath.evaluate("//responsecollection/response/documentresult/record", searchResultDOM.getDocumentElement(), XPathConstants.NODESET); java.lang.Long hitCount = java.lang.Long .parseLong((String) (xPath.evaluate("//responsecollection/response/documentresult/@hitCount", searchResultDOM.getDocumentElement(), XPathConstants.STRING))); SearchResultList searchResultList = new SearchResultList(); searchResultList.setHitCount(hitCount); for (int i = 0; i < nodeList.getLength(); ++i) { Node node = nodeList.item(i); SearchResult searchResult = new SearchResult(); Node shortRecordNode = (Node) xPath.evaluate("field[@name='domsshortrecord']", node, XPathConstants.NODE); if (shortRecordNode != null) { Node shortRecord = DOM.stringToDOM(shortRecordNode.getTextContent()).getDocumentElement(); String pid = xPath.evaluate("pid", shortRecord); String title = xPath.evaluate("title", shortRecord); searchResult.setPid(pid); if (title != null && !title.equals("")) { searchResult.setTitle(title); } else { searchResult.setTitle(pid); } searchResult.setType(xPath.evaluate("type", shortRecord)); searchResult.setSource(xPath.evaluate("source", shortRecord)); searchResult.setTime(xPath.evaluate("time", shortRecord)); searchResult.setDescription(xPath.evaluate("description", shortRecord)); searchResult.setState(xPath.evaluate("state", shortRecord)); try { searchResult.setCreatedDate(DatatypeConverter .parseDateTime(xPath.evaluate("createdDate", shortRecord)).getTimeInMillis()); } catch (IllegalArgumentException ignored) { } try { searchResult.setModifiedDate(DatatypeConverter .parseDateTime(xPath.evaluate("modifiedDate", shortRecord)).getTimeInMillis()); } catch (IllegalArgumentException ignored) { } } else { String pid = xPath.evaluate("field[@name='recordID']/text()", node); pid = pid.substring(pid.indexOf(':') + 1); searchResult.setPid(pid); searchResult.setTitle(pid); searchResult.setDescription(""); searchResult.setSource(""); searchResult.setState(""); searchResult.setTime(""); searchResult.setType(""); } searchResultList.getSearchResult().add(searchResult); } return searchResultList; } catch (XPathExpressionException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } @Override public void lockForWriting() throws InvalidCredentialsException, MethodFailedException { lock.lockForWriting(); //DO the lock try { //Execute a command to flush the unflushed triple changes. fedora.flushTripples(); } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } @Override public void unlockForWriting() throws InvalidCredentialsException, MethodFailedException { lock.unlockForWriting(); } @Override public User createTempAdminUser(@WebParam(name = "username", targetNamespace = "") String username, @WebParam(name = "roles", targetNamespace = "") List<String> roles) throws InvalidCredentialsException, MethodFailedException { try { dk.statsbiblioteket.doms.authchecker.user.User auser = authChecker.createTempAdminUser(username, roles); User user = new User(); user.setUsername(auser.getUsername()); user.setPassword(auser.getPassword()); return user; } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } @Override public List<String> getContentModelsInCollection(String collectionPid) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { try { log.trace("Entering getContentModelsInCollection with param collectionPid=" + collectionPid); List<String> objects = fedora.getContentModelsInCollection(collectionPid); return objects; } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } @Override public List<Method> getMethods(@WebParam(name = "pid", targetNamespace = "") String pid) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { try { List<dk.statsbiblioteket.doms.central.connectors.fedora.methods.generated.Method> internalMethodList = fedora .getStaticMethods(pid, null); internalMethodList.addAll(fedora.getDynamicMethods(pid, null)); List<Method> externalMethods = new ArrayList<Method>(); for (dk.statsbiblioteket.doms.central.connectors.fedora.methods.generated.Method internalmethod : internalMethodList) { Method externalMethod = new Method(); externalMethod.setName(internalmethod.getName()); externalMethod.setType(internalmethod.getType()); Parameters externalParameters = new Parameters(); externalMethod.setParameters(externalParameters); for (Parameter internalparameter : internalmethod.getParameters().getParameter()) { dk.statsbiblioteket.doms.central.Parameter externalParameter = new dk.statsbiblioteket.doms.central.Parameter(); externalParameter.setConfig(internalparameter.getConfig()); externalParameter.setName(internalparameter.getName()); externalParameter.setRepeatable(internalparameter.isRepeatable()); externalParameter.setRequired(internalparameter.isRequired()); externalParameter.setType(internalparameter.getType()); externalParameters.getParameter().add(externalParameter); } externalMethods.add(externalMethod); } return externalMethods; } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } @Override public String invokeMethod(@WebParam(name = "cmpid", targetNamespace = "") String cmpid, @WebParam(name = "methodName", targetNamespace = "") String methodName, @WebParam(name = "parameters", targetNamespace = "") List<Pair> parameters) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { try { Map<String, List<String>> parameterMap = new HashMap<String, List<String>>(); for (Pair parameter : parameters) { if (!parameterMap.containsKey(parameter.getName())) { parameterMap.put(parameter.getName(), new ArrayList<String>()); } parameterMap.get(parameter.getName()).add(parameter.getValue()); } return fedora.invokeMethod(cmpid, methodName, parameterMap, null); } catch (BackendMethodFailedException e) { log.warn("Failed to execute method", e); throw new MethodFailedException("Method failed to execute", "Method failed to execute", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } @Override public List<Link> getObjectLinks(@WebParam(name = "pid", targetNamespace = "") String pid, @WebParam(name = "asOfTime", targetNamespace = "") long asOfTime) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { try { List<LinkPattern> internalLinkList = fedora.getLinks(pid, (asOfTime >= 0 ? asOfTime : null)); List<Link> externalMethods = new ArrayList<Link>(); for (LinkPattern linkPattern : internalLinkList) { Link externalLink = new Link(); externalLink.setName(linkPattern.getName()); externalLink.setDescription(linkPattern.getDescription()); externalLink.setValue(linkPattern.getValue()); externalMethods.add(externalLink); } return externalMethods; } catch (BackendMethodFailedException e) { log.warn("Failed to get Links", e); throw new MethodFailedException("Links failed to be gotten", "Links failed to be gotten", e); } catch (BackendInvalidCredsException e) { log.debug("User supplied invalid credentials", e); throw new InvalidCredentialsException("Invalid Credentials Supplied", "Invalid Credentials Supplied", e); } catch (BackendInvalidResourceException e) { log.debug("Invalid resource requested", e); throw new InvalidResourceException("Invalid Resource Requested", "Invalid Resource Requested", e); } catch (Exception e) { log.warn("Caught Unknown Exception", e); throw new MethodFailedException("Server error", "Server error", e); } } private List<RecordDescription> transform(List<UpdateTrackerRecord> input) { List<RecordDescription> output = new ArrayList<RecordDescription>(); for (UpdateTrackerRecord updateTrackerRecord : input) { output.add(transform(updateTrackerRecord)); } return output; } private RecordDescription transform(UpdateTrackerRecord updateTrackerRecord) { RecordDescription a = new RecordDescription(); a.setCollectionPid(updateTrackerRecord.getCollectionPid()); a.setEntryContentModelPid(updateTrackerRecord.getEntryContentModelPid()); a.setPid(updateTrackerRecord.getPid()); a.setState(updateTrackerRecord.getState()); a.setDate(updateTrackerRecord.getDate().getTime()); a.setRecordDate(updateTrackerRecord.getRecordDate().getTime()); return a; } protected Credentials getCredentials() { HttpServletRequest request = getServletRequest(); Credentials creds = (Credentials) request.getAttribute("Credentials"); if (creds == null) { log.warn("Attempted call at Central without credentials"); creds = new Credentials("", ""); } return creds; } private HttpServletRequest getServletRequest() { if (context != null) { return (HttpServletRequest) context.getMessageContext().get(MessageContext.SERVLET_REQUEST); } else { return restRequest; } } private void logEntering(String method, String... params) { if (log.isTraceEnabled()) { String command = method + "("; for (String param : params) { command = command + " " + param + ","; } command = command.substring(0, command.length() - 1) + ")"; log.trace("Entering " + command); } } private static List<Relation> convertRelations(List<FedoraRelation> fedorarels) { List<Relation> outrealtions = new ArrayList<Relation>(); for (FedoraRelation fedorarel : fedorarels) { Relation outrel = new Relation(); outrel.setSubject(fedorarel.getSubject()); outrel.setPredicate(fedorarel.getPredicate()); outrel.setObject(fedorarel.getObject()); outrel.setLiteral(fedorarel.isLiteral()); outrealtions.add(outrel); } return outrealtions; } }