dk.statsbiblioteket.doms.central.CentralWebserviceImpl.java Source code

Java tutorial

Introduction

Here is the source code for dk.statsbiblioteket.doms.central.CentralWebserviceImpl.java

Source

/*
 * $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;
    }

}