text:
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;
    }

}


text:
/* AUTO-GENERATED FILE.  DO NOT MODIFY.
 *
 * This class was automatically generated by the
 * aapt tool from the resource data it found.  It
 * should not be modified by hand.
 */

package com.produce.ciro.bchart4;

public final class R {
    public static final class array {
        public static final int drawer_array=0x7f070000;
    }
    public static final class attr {
    }
    public static final class dimen {
        /**  Default screen margins, per the Android Design guidelines.

         Customize dimensions originally defined in res/values/dimens.xml (such as
         screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.

         */
        public static final int activity_horizontal_margin=0x7f050000;
        public static final int activity_vertical_margin=0x7f050001;
        public static final int domain_label_font_size=0x7f050004;
        public static final int domain_tick_label_font_size=0x7f050007;
        public static final int legend_text_font_size=0x7f050008;
        public static final int pie_segment_label_font_size=0x7f050002;
        public static final int range_label_font_size=0x7f050005;
        public static final int range_tick_label_font_size=0x7f050006;
        public static final int title_font_size=0x7f050003;
    }
    public static final class drawable {
        public static final int drawer_shadow=0x7f020000;
        public static final int ic_drawer=0x7f020001;
        public static final int ic_launcher=0x7f020002;
    }
    public static final class id {
        public static final int LinearLayout01=0x7f0a0006;
        public static final int ask=0x7f0a0012;
        public static final int askname=0x7f0a0011;
        public static final int bid=0x7f0a0010;
        public static final int bidname=0x7f0a000f;
        public static final int chart=0x7f0a0003;
        public static final int content_frame=0x7f0a0001;
        public static final int drawer_layout=0x7f0a0000;
        public static final int high=0x7f0a000a;
        public static final int highname=0x7f0a0009;
        public static final int last=0x7f0a000e;
        public static final int lastname=0x7f0a000d;
        public static final int left_drawer=0x7f0a0002;
        public static final int low=0x7f0a000c;
        public static final int lowname=0x7f0a000b;
        public static final int menu_settings=0x7f0a0017;
        public static final int orderbookchart=0x7f0a0004;
        public static final int tickerList=0x7f0a0005;
        public static final int timestamp=0x7f0a0008;
        public static final int timestampname=0x7f0a0007;
        public static final int volume=0x7f0a0016;
        public static final int volumename=0x7f0a0015;
        public static final int vwap=0x7f0a0014;
        public static final int vwapname=0x7f0a0013;
    }
    public static final class layout {
        public static final int activity_main=0x7f030000;
        public static final int drawer_list_item=0x7f030001;
        public static final int fragment_chart=0x7f030002;
        public static final int fragment_orderbook_chart=0x7f030003;
        public static final int fragment_ticker=0x7f030004;
        public static final int ticker_items=0x7f030005;
    }
    public static final class menu {
        public static final int main=0x7f090000;
    }
    public static final class string {
        public static final int app_name=0x7f060000;
        public static final int apptime_default=0x7f06000b;
        public static final int apptime_saved=0x7f06000c;
        public static final int ask=0x7f060008;
        public static final int bid=0x7f060007;
        public static final int drawer_close=0x7f060002;
        public static final int drawer_open=0x7f060001;
        public static final int high=0x7f060004;
        public static final int last=0x7f060006;
        public static final int low=0x7f060005;
        public static final int timestamp=0x7f060003;
        public static final int volume=0x7f06000a;
        public static final int vwap=0x7f060009;
    }
    public static final class style {
        /**
        Base application theme, dependent on API level. This theme is replaced
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.

            Theme customizations available in newer API levels can go in
            res/values-vXX/styles.xml, while customizations related to
            backward-compatibility can go here.

        Base application theme for API 11+. This theme completely replaces
        AppBaseTheme from res/values/styles.xml on API 11+ devices.

 API 11 theme customizations can go here.

        Base application theme for API 14+. This theme completely replaces
        AppBaseTheme from BOTH res/values/styles.xml and
        res/values-v11/styles.xml on API 14+ devices.

 API 14 theme customizations can go here.
         */
        public static final int AppBaseTheme=0x7f080000;
        /**  Application theme.
 All customizations that are NOT specific to a particular API-level can go here.
         */
        public static final int AppTheme=0x7f080001;
    }
    public static final class xml {
        public static final int line_point_formatter=0x7f040000;
        public static final int line_point_formatter_with_plf1=0x7f040001;
        public static final int line_point_formatter_with_plf2=0x7f040002;
    }
}

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>MemoryOutputStream (apache-cassandra API)</title>
<meta name="date" content="2016-06-06">
<link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

org.apache.cassandra.io.util

Class MemoryOutputStream

java.lang.Object

java.io.OutputStream

org.apache.cassandra.io.util.MemoryOutputStream

All Implemented Interfaces:

java.io.Closeable, java.io.Flushable, java.lang.AutoCloseable

public class MemoryOutputStream
extends java.io.OutputStream

This class provides a way to stream the writes into the Memory

Constructor Summary

Constructors

Constructor and Description

MemoryOutputStream(Memory mem)

Method Summary

All Methods Instance Methods Concrete Methods

Modifier and Type
Method and Description

int
position()

void
write(byte[] b,
     int off,
     int len)

void
write(int b)

Methods inherited from class java.io.OutputStream

close, flush, write

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructor Detail

MemoryOutputStream

public MemoryOutputStream(Memory mem)

Method Detail

write

public void write(int b)

Specified by:

write in class java.io.OutputStream

write

public void write(byte[] b,
                  int off,
                  int len)
           throws java.io.IOException

Overrides:

write in class java.io.OutputStream

Throws:

java.io.IOException

position

public int position()

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

Copyright © 2016 The Apache Software Foundation


text:
using Raven.HttpClientEngine.DelegatingHandlers;
using Raven.HttpClientEngine.MessageOptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace Raven.HttpClientEngine
{
    public class HttpClientEngine
    {
        private HttpClient _client;
        private HttpRequestMessageOptions _requestOptions;
        private HttpResponseMessageOptions _responseOptions;

        public HttpClientEngine(HttpRequestMessageOptions requestOptions, HttpResponseMessageOptions responseOptions)
        {
            _requestOptions = requestOptions;
            _responseOptions = responseOptions;
            _client = HttpClientFactory.Create(
                 new HttpHeaderHandler(_requestOptions),
                 new HttpTraceLogHandler(_responseOptions),
                 new HttpHeaderHandler(_requestOptions)
             );
        }

        public async Task<string> SendAsync()
        {
            using (HttpRequestMessage request = new HttpRequestMessage())
            {
                var response = await _client.SendAsync(request);

                return await response.Content.ReadAsStringAsync();
            }
        }
    }
}


text:
Guard::Jaspec supports the automatic running of [Jaspec](https://github.com/gisikw/jaspec) JavaScript specs.

## Installation

Please ensure you have [Guard](http://github.com/guard/guard) installed before you continue.

Add the following to your application's Gemfile:

    group :development do
      gem 'guard-jaspec'
    end

And then execute:

    $ bundle

Add Guard::Jaspec to your Guardfile by running:

    $ guard init jaspec

## Usage

Please refer to the [Guard usage doc](http://github.com/guard/guard#readme)

## Example Guardfile

This is the default Guardfile configuration, and it assumes a Rails-like asset structure. If your JavaScript source files or specs are in different directories, you'll want to modify this. This configuration likewise assumes that you're using the same language (JavaScript or CoffeeScript) between your source files and specs.

```ruby
guard :jaspec do
  watch(%r{^spec/javascripts/(.\*)Spec\.(js|coffee)$})
  watch(%r{^app/assets/javascripts/(.\*)\.(js|coffee)$}) { |m| "spec/javascripts/#{m[1]}Spec.#{m[2]}" }
end
```

## Options

### List of available options

```ruby
all_on_start: false   # run all specs on startup, default: true
```

## Contributing

1. Fork it ( https://github.com/gisikw/guard-jaspec/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request


text:
package com.microsoft.bingads.reporting;

import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;
import javax.xml.bind.annotation.XmlType;

/**
 *
Java class for BudgetSummaryReportColumn.
 *
 *
The following schema fragment specifies the expected content contained within this class.
 *

 *

 * <simpleType name="BudgetSummaryReportColumn">
 *   <restriction base="{http://www.w3.org/2001/XMLSchema}string">
 *     <enumeration value="AccountName"/>
 *     <enumeration value="AccountNumber"/>
 *     <enumeration value="AccountId"/>
 *     <enumeration value="CampaignName"/>
 *     <enumeration value="CampaignId"/>
 *     <enumeration value="Date"/>
 *     <enumeration value="CurrencyCode"/>
 *     <enumeration value="MonthlyBudget"/>
 *     <enumeration value="DailySpend"/>
 *     <enumeration value="MonthToDateSpend"/>
 *   </restriction>
 * </simpleType>
 *

 *
 */
@XmlType(name = "BudgetSummaryReportColumn")
@XmlEnum
public enum BudgetSummaryReportColumn {

    @XmlEnumValue("AccountName")
    ACCOUNT_NAME("AccountName"),
    @XmlEnumValue("AccountNumber")
    ACCOUNT_NUMBER("AccountNumber"),
    @XmlEnumValue("AccountId")
    ACCOUNT_ID("AccountId"),
    @XmlEnumValue("CampaignName")
    CAMPAIGN_NAME("CampaignName"),
    @XmlEnumValue("CampaignId")
    CAMPAIGN_ID("CampaignId"),
    @XmlEnumValue("Date")
    DATE("Date"),
    @XmlEnumValue("CurrencyCode")
    CURRENCY_CODE("CurrencyCode"),
    @XmlEnumValue("MonthlyBudget")
    MONTHLY_BUDGET("MonthlyBudget"),
    @XmlEnumValue("DailySpend")
    DAILY_SPEND("DailySpend"),
    @XmlEnumValue("MonthToDateSpend")
    MONTH_TO_DATE_SPEND("MonthToDateSpend");
    private final String value;

    BudgetSummaryReportColumn(String v) {
        value = v;
    }

    public String value() {
        return value;
    }

    public static BudgetSummaryReportColumn fromValue(String v) {
        for (BudgetSummaryReportColumn c: BudgetSummaryReportColumn.values()) {
            if (c.value.equals(v)) {
                return c;
            }
        }
        throw new IllegalArgumentException(v);
    }

}


text:
package se.kth.mf2063.internetdrone;

/**
 * Created by eminsaf on 11/9/15.
 */
import java.io.Serializable;

enum MessageType {MAVLINK, WIFION, WIFIOFF};

public class Message implements Serializable {
    private static final long serialVersionUID = 124234678453620001L;
    private byte [] byteArray;
    private MessageType messageType;

    public byte[] getByteArray() {
        return byteArray;
    }

    public void setByteArray(byte[] byteArray) {
        this.byteArray = byteArray;
    }

    public MessageType getMessageType() {
        return messageType;
    }

    public void setMessageType(MessageType messageType) {
        this.messageType = messageType;
    }
}


text:
const { Model } = require('../../../../');

class JoinModel extends Model {
  static get tableName() {
    return this.name;
  }
}

module.exports = JoinModel;


text:
==================================================================================================
ValidateMigrationTestType
==================================================================================================

.. describe:: ValidateMigrationTestType

    Types of tests available for validateMigration.

    .. py:data:: ValidateMigrationTestType.compatibilityTests

        Tests that examine both the virtual machine and the destination host or cluster; the destination resource pool is irrelevant. This set excludes tests that fall into the diskAccessibilityTests group.

    .. py:data:: ValidateMigrationTestType.diskAccessibilityTests

        Tests that check that the destination host or cluster can see the datastores where the virtual machine's virtual disks are currently located. The destination resource pool is irrelevant. If you are planning to relocate the virtual disks, do not use these tests; instead examine the relevant datastore objects for your planned disk locations to see if they are accessible to the destination host.

    .. py:data:: ValidateMigrationTestType.resourceTests

        Tests that check that the destination resource pool can support the virtual machine if it is powered on. The destination host or cluster is relevant because it will affect the amount of overhead memory required to run the virtual machine.

    .. py:data:: ValidateMigrationTestType.sourceTests

        Tests that examine only the configuration of the virtual machine and its current host; the destination resource pool and host or cluster are irrelevant.


text:
<?php

/**
 * Class Offers
 * @property Offer_m $offer_m
 */
class Offers extends Back_controller
{

    private $error = '';

    public function __construct()
    {

        parent::__construct();

        if (!$this->isLogged()) {
            redirect(site_url('admin/auth/login'));
        }
        $this->load->model('offer_m');
        $this->lang->load('offer');
    }

    public function index()
    {

        $this->template->title($this->lang->line('heading_title'));

        $this->getOfferList();
    }

    public function add()
    {
        $this->template->title($this->lang->line('heading_title'));

        if ($this->input->post() && $this->validateOfferForm()) {

            $this->offer_m->addOffersType($this->input->post());

            $this->session->set_flashdata('success', $this->lang->line('text_success'));

            redirect(base_url('admin/offers?token=' . $this->token));
        }
        $this->getOfferForm();
    }

    public function edit()
    {
        $this->template->title($this->lang->line('heading_title'));

        if ($this->input->post() && $this->validateOfferForm()) {
            $this->offer_m->editOffersType($this->input->get('offer_id'), $this->input->post());
            $this->session->set_flashdata('success', $this->lang->line('text_success'));
            redirect(base_url('admin/offers?token=' . $this->token));
        }
        $this->getOfferForm();

    }

    public function delete()
    {

    }

    /**
     * Adding store from offer page using ajax call
     *
     */
    public function store_add()
    {
        if ($this->input->post('data')) {
            parse_str($this->input->post('data'), $form);

            $this->load->model('stores/store_m');
            $this->store_m->addStore($form['stores']);
            echo 1;
        }
        exit;
    }

    public function getOfferList()
    {
        date_default_timezone_set('Asia/Kolkata');
        $currentTime = strtotime(date('Y-m-d H:i:s'));
        $log = APPPATH . 'logs' . DIRECTORY_SEPARATOR . 'log.txt';

        if (file_exists($log))
            $oldTime = strtotime(file_get_contents($log)) + 86400;
        else $oldTime = 0;

        if ($currentTime > $oldTime) {

            $this->fetch_and_insert_offers();
        }

        //Breadcrumbs
        $data['breadcrumbs'][] = array();
        $data['breadcrumbs'] = array(
            array(
                'text' => $this->lang->line('text_home'),
                'href' => base_url('admin/dashboard?token=' . $this->token)
            ),
            array(
                'text' => $this->lang->line('heading_title'),
                'href' => base_url('admin/offers?token=' . $this->token)
            )
        );
        $data['heading_title'] = $this->lang->line('heading_title');

        $data['text_list'] = $this->lang->line('text_list');
        $data['text_no_results'] = $this->lang->line('text_no_results');
        $data['text_confirm'] = $this->lang->line('text_confirm');
        $data['column_name'] = $this->lang->line('column_name');

        $data['button_edit'] = $this->lang->line('button_edit');
        $data['button_delete'] = $this->lang->line('button_delete');
        $data['button_sync'] = $this->lang->line('button_sync');

        if (isset($this->error['warning'])) {
            $data['error_warning'] = $this->error['warning'];
        } else {
            $data['error_warning'] = '';
        }

        if ($this->session->userdata('success')) {
            $data['success'] = $this->session->userdata('success');

            $this->session->unset_userdata('success');
        } else {
            $data['success'] = '';
        }

        if ($this->input->post('selected')) {
            $data['selected'] = (array)$this->input->post('selected');
        } else {
            $data['selected'] = array();
        }

        $data['token'] = $this->token;

        $data['add'] = base_url('admin/offers/add?token=' . $this->token);
        $data['delete'] = base_url('admin/offers/delete?token=' . $this->token);
        $data['sync'] = base_url('admin/offers/rebuild?token=' . $this->token);
        $data['offers'] = $this->offer_m->getOffers();
        $data['offers_type']=$this->offer_m->get_offer_type_list();
        $data['stores']=$this->offer_m->get_store_list();

        $this->template->build('offers/offer_list', $data);
    }

    protected function getOfferTypeList()
    {
        $data['breadcrumbs'] = array(
            array(
                'text' => $this->lang->line('text_home'),
                'href' => base_url('admin/dashboard?token=' . $this->token)
            ),
            array(
                'text' => $this->lang->line('heading_title'),
                'href' => base_url('admin/offers?token=' . $this->token)
            )
        );

        $data['add'] = base_url('admin/offers/add?token=' . $this->token);
        $data['sync'] = base_url('admin/offers/sync?token=' . $this->token);
        $data['cancel'] = base_url('admin/offers?token=' . $this->token);
        $data['delete'] = base_url();
        $data['offers'] = $this->offer_m->getOffersType();

        $this->load->model('stores/store_m');
        $temp = $this->store_m->getStores();
        $stores = [];
        foreach ($temp as $item) {
            $stores[$item['store_id']] = $item['name'];
        }

        $data['stores'] = $stores;

        $data['heading_title'] = $this->lang->line('heading_title');

        $data['text_list'] = $this->lang->line('text_list');
        $data['text_no_results'] = $this->lang->line('text_no_results');
        $data['text_confirm'] = $this->lang->line('text_confirm');
        $data['column_name'] = $this->lang->line('column_name');
        $data['column_store'] = $this->lang->line('column_store');
        $data['column_status'] = $this->lang->line('column_status');
        $data['column_action'] = $this->lang->line('column_action');

        $data['button_add'] = $this->lang->line('button_add');
        $data['button_edit'] = $this->lang->line('button_edit');
        $data['button_delete'] = $this->lang->line('button_delete');
        $data['button_sync'] = $this->lang->line('button_sync');

        if (isset($this->error['warning'])) {
            $data['error_warning'] = $this->error['warning'];
        } else {
            $data['error_warning'] = '';
        }

        if ($this->session->userdata('success')) {
            $data['success'] = $this->session->userdata('success');

            $this->session->unset_userdata('success');
        } else {
            $data['success'] = '';
        }

        if ($this->input->post('selected')) {
            $data['selected'] = (array)$this->input->post('selected');
        } else {
            $data['selected'] = array();
        }

        $data['token'] = $this->token;
        $this->template->build('offer_type_list', $data);
    }

    protected function getOfferForm()
    {
        $data['heading_title'] = $this->lang->line('heading_title');
        $data['text_form'] = !$this->input->get('offer_id') ? $this->lang->line('text_add') : $this->lang->line('text_edit');
        $data['text_enabled'] = $this->lang->line('text_enabled');
        $data['text_disabled'] = $this->lang->line('text_disabled');

        $data['entry_name'] = $this->lang->line('entry_name');
        $data['entry_store'] = $this->lang->line('entry_store');
        $data['entry_status'] = $this->lang->line('entry_status');
        $data['entry_store_placeholder'] = $this->lang->line('entry_store_placeholder');
        $data['button_save'] = $this->lang->line('button_save');
        $data['button_cancel'] = $this->lang->line('button_cancel');

        $data['error_warning'] = isset($this->error['warning']) ? $this->error['warning'] : '';

        $data['error_name'] = isset($this->error['name']) ? $this->error['name'] : '';
        $data['error_store'] = isset($this->error['store']) ? $this->error['store'] : '';

        $data['breadcrumbs'] = array(
            array(
                'text' => $this->lang->line('text_home'),
                'href' => base_url('admin/dashboard?token=' . $this->token)
            ),
            array(
                'text' => $this->lang->line('heading_title'),
                'href' => base_url('admin/offers?token=' . $this->token)
            ),
        );

        if ($this->input->get('offer_id')) {
            $data['action'] = base_url('admin/offers/edit?offer_id=' . $this->input->get('offer_id') . '&token=' . $this->token);
        } else {
            $data['action'] = base_url('admin/offers/add?token=' . $this->token);
        }
        $data['cancel'] = base_url('admin/offers?token=' . $this->token);

        if ($this->input->get('offer_id') && !$this->input->post()) {
            $offer_info = $this->offer_m->getOfferType($this->input->get('offer_id'));
        }

        if ($this->input->post('name')) {
            $data['name'] = $this->input->post('name');
        } elseif (!empty($offer_info['name'])) {
            $data['name'] = $offer_info['name'];
        } else {
            $data['name'] = '';
        }

        $this->load->model('stores/store_m');
        $stores = $this->store_m->getStores();
        if ($this->input->post('store_id')) {
            $data['store_id'] = $this->input->post('store_id');
        } elseif (!empty($offer_info['store_id'])) {
            $data['store_id'] = $offer_info['store_id'];
            $data['stores'] = $stores;
        } else {
            $data['stores'] = $stores;
        }

        if ($this->input->post('status')) {
            $data['status'] = $this->input->post('status');
        } elseif (!empty($offer_info['status'])) {
            $data['status'] = $offer_info['status'];
        } else {
            $data['status'] = TRUE;
        }
        $data['token'] = $this->token;

        $this->template->build('offer_form', $data);
    }

    protected function validateOfferForm()
    {
        $value = $this->input->post();

        if ((utf8_strlen($value['name']) < 2) || (utf8_strlen($value['name']) > 255)) {
            $this->error['name'] = $this->lang->line('error_name');
        }
        if ($value['store_id'] == '') {
            $this->error['store'] = $this->lang->line('error_store');
        }
        if ($this->error && !isset($this->error['warning'])) {
            $this->error['warning'] = $this->lang->line('error_warning');
        }

        return !$this->error;
    }

    protected function fetch_and_insert_offers()
    {
        $this->load->library('flipkart');
        $all_offer_url = 'https://affiliate-api.flipkart.net/affiliate/offers/v1/all/json';
        $dotd_url = 'https://affiliate-api.flipkart.net/affiliate/offers/v1/dotd/json';
        $flipkart = new Flipkart($this->fk_affID, $this->fk_token, 'json');

        $offers_type = $this->offer_m->offersType();

        $this->db->truncate('offers');
        $this->db->truncate('offers_image');
        $this->load->model('stores/store_m');
        $stores = $this->store_m->getStores();

        $all_offer = $flipkart->call_url($all_offer_url);

        if ($all_offer) {
            $all_offer = json_decode($all_offer, TRUE);
            $totalRows = count($all_offer['allOffersList']);
            $i = 0;
            foreach ($all_offer['allOffersList'] as $offer) {
                $this->offer_m->addOffer($offer);
                $i++;
            }
            if ($i == $totalRows) {
                $this->create_log();
            } else {
                die('Could not Sync Completely');
            }
        }

        /*if ($dotd_url) {
            $dotd = $flipkart->call_url($dotd_url);
        }*/
    }

    protected function create_log()
    {
        $content = date('Y-m-d H:i:s');
        $fp = fopen(APPPATH . 'logs' . DIRECTORY_SEPARATOR . "log.txt", "w+") or die('Can\'t Create log file');
        fwrite($fp, $content);
        fclose($fp);
    }
}


text:
"""Built-in share type properties."""

import re

from oslo_config import cfg
from oslo_db import exception as db_exception
from oslo_log import log
from oslo_utils import strutils
from oslo_utils import uuidutils
import six

from manila.common import constants
from manila import context
from manila import db
from manila import exception
from manila.i18n import _
from manila.i18n import _LE

CONF = cfg.CONF
LOG = log.getLogger(__name__)

def create(context, name, extra_specs=None, is_public=True, projects=None):
    """Creates share types."""
    extra_specs = extra_specs or {}
    projects = projects or []

    if constants.ExtraSpecs.SNAPSHOT_SUPPORT not in list(extra_specs):
        extra_specs[constants.ExtraSpecs.SNAPSHOT_SUPPORT] = 'True'

    try:
        get_valid_required_extra_specs(extra_specs)
    except exception.InvalidExtraSpec as e:
        raise exception.InvalidShareType(reason=six.text_type(e))

    try:
        type_ref = db.share_type_create(context,
                                        dict(name=name,
                                             extra_specs=extra_specs,
                                             is_public=is_public),
                                        projects=projects)
    except db_exception.DBError as e:
        LOG.exception(_LE('DB error: %s'), e)
        raise exception.ShareTypeCreateFailed(name=name,
                                              extra_specs=extra_specs)
    return type_ref

def destroy(context, id):
    """Marks share types as deleted."""
    if id is None:
        msg = _("id cannot be None")
        raise exception.InvalidShareType(reason=msg)
    else:
        db.share_type_destroy(context, id)

def get_all_types(context, inactive=0, search_opts=None):
    """Get all non-deleted share_types.

    """
    search_opts = search_opts or {}
    filters = {}

    if 'is_public' in search_opts:
        filters['is_public'] = search_opts.pop('is_public')

    share_types = db.share_type_get_all(context, inactive, filters=filters)

    for type_name, type_args in share_types.items():
        required_extra_specs = {}
        try:
            required_extra_specs = get_valid_required_extra_specs(
                type_args['extra_specs'])
        except exception.InvalidExtraSpec as e:
            values = {
                'share_type': type_name,
                'error': six.text_type(e)
            }
            LOG.exception(_LE('Share type %(share_type)s has invalid required'
                              ' extra specs: %(error)s'), values)

        type_args['required_extra_specs'] = required_extra_specs

    if search_opts:
        LOG.debug("Searching by: %s", search_opts)

        def _check_extra_specs_match(share_type, searchdict):
            for k, v in searchdict.items():
                if (k not in share_type['extra_specs'].keys()
                        or share_type['extra_specs'][k] != v):
                    return False
            return True

        # search_option to filter_name mapping.
        filter_mapping = {'extra_specs': _check_extra_specs_match}

        result = {}
        for type_name, type_args in share_types.items():
            # go over all filters in the list
            for opt, values in search_opts.items():
                try:
                    filter_func = filter_mapping[opt]
                except KeyError:
                    # no such filter - ignore it, go to next filter
                    continue
                else:
                    if filter_func(type_args, values):
                        result[type_name] = type_args
                        break
        share_types = result
    return share_types

def get_share_type(ctxt, id, expected_fields=None):
    """Retrieves single share type by id."""
    if id is None:
        msg = _("id cannot be None")
        raise exception.InvalidShareType(reason=msg)

    if ctxt is None:
        ctxt = context.get_admin_context()

    return db.share_type_get(ctxt, id, expected_fields=expected_fields)

def get_share_type_by_name(context, name):
    """Retrieves single share type by name."""
    if name is None:
        msg = _("name cannot be None")
        raise exception.InvalidShareType(reason=msg)

    return db.share_type_get_by_name(context, name)

def get_share_type_by_name_or_id(context, share_type=None):
    if not share_type:
        share_type_ref = get_default_share_type(context)
        if not share_type_ref:
            msg = _("Default share type not found")
            raise exception.ShareTypeNotFound(reason=msg)
        return share_type_ref

    if uuidutils.is_uuid_like(share_type):
        return get_share_type(context, share_type)
    else:
        return get_share_type_by_name(context, share_type)

def get_default_share_type(ctxt=None):
    """Get the default share type."""
    name = CONF.default_share_type

    if name is None:
        return {}

    if ctxt is None:
        ctxt = context.get_admin_context()

    try:
        return get_share_type_by_name(ctxt, name)
    except exception.ShareTypeNotFoundByName as e:
        # Couldn't find share type with the name in default_share_type
        # flag, record this issue and move on
        # TODO(zhiteng) consider add notification to warn admin
        LOG.exception(_LE('Default share type is not found, '
                          'please check default_share_type config: %s'),
                      e)

def get_share_type_extra_specs(share_type_id, key=False):
    share_type = get_share_type(context.get_admin_context(),
                                share_type_id)
    extra_specs = share_type['extra_specs']
    if key:
        if extra_specs.get(key):
            return extra_specs.get(key)
        else:
            return False
    else:
        return extra_specs

def get_required_extra_specs():
    return constants.ExtraSpecs.REQUIRED

def get_undeletable_extra_specs():
    return constants.ExtraSpecs.UNDELETABLE

def get_tenant_visible_extra_specs():
    return constants.ExtraSpecs.TENANT_VISIBLE

def get_boolean_extra_specs():
    return constants.ExtraSpecs.BOOLEAN

def is_valid_required_extra_spec(key, value):
    """Validates required extra_spec value.

    :param key: extra_spec name
    :param value: extra_spec value
    :return: None if provided extra_spec is not required
             True/False if extra_spec is required and valid or not.
    """
    if key not in get_required_extra_specs():
        return

    if key == constants.ExtraSpecs.DRIVER_HANDLES_SHARE_SERVERS:
        return strutils.bool_from_string(value, default=None) is not None

    return False

def get_valid_required_extra_specs(extra_specs):
    """Returns required extra specs from dict.

    Returns None if extra specs are not valid, or if
    some required extras specs is missed.
    """
    extra_specs = extra_specs or {}

    missed_extra_specs = set(get_required_extra_specs()) - set(extra_specs)

    if missed_extra_specs:
        specs = ",".join(missed_extra_specs)
        msg = _("Required extra specs '%s' not specified.") % specs
        raise exception.InvalidExtraSpec(reason=msg)

    required_extra_specs = {}

    for k in get_required_extra_specs():
        value = extra_specs.get(k, '')
        if not is_valid_required_extra_spec(k, value):
            msg = _("Value of required extra_spec %s is not valid") % k
            raise exception.InvalidExtraSpec(reason=msg)

        required_extra_specs[k] = value

    return required_extra_specs

def add_share_type_access(context, share_type_id, project_id):
    """Add access to share type for project_id."""
    if share_type_id is None:
        msg = _("share_type_id cannot be None")
        raise exception.InvalidShareType(reason=msg)
    return db.share_type_access_add(context, share_type_id, project_id)

def remove_share_type_access(context, share_type_id, project_id):
    """Remove access to share type for project_id."""
    if share_type_id is None:
        msg = _("share_type_id cannot be None")
        raise exception.InvalidShareType(reason=msg)
    return db.share_type_access_remove(context, share_type_id, project_id)

def share_types_diff(context, share_type_id1, share_type_id2):
    """Returns a 'diff' of two share types and whether they are equal.

    Returns a tuple of (diff, equal), where 'equal' is a boolean indicating
    whether there is any difference, and 'diff' is a dictionary with the
    following format:
    {'extra_specs': {
    'key1': (value_in_1st_share_type, value_in_2nd_share_type),
    'key2': (value_in_1st_share_type, value_in_2nd_share_type),
    ...}
    """

    def _dict_diff(dict1, dict2):
        res = {}
        equal = True
        if dict1 is None:
            dict1 = {}
        if dict2 is None:
            dict2 = {}
        for k, v in dict1.items():
            res[k] = (v, dict2.get(k))
            if k not in dict2 or res[k][0] != res[k][1]:
                equal = False
        for k, v in dict2.items():
            res[k] = (dict1.get(k), v)
            if k not in dict1 or res[k][0] != res[k][1]:
                equal = False
        return (res, equal)

    all_equal = True
    diff = {}
    share_type1 = get_share_type(context, share_type_id1)
    share_type2 = get_share_type(context, share_type_id2)

    extra_specs1 = share_type1.get('extra_specs')
    extra_specs2 = share_type2.get('extra_specs')
    diff['extra_specs'], equal = _dict_diff(extra_specs1, extra_specs2)
    if not equal:
        all_equal = False

    return (diff, all_equal)

def get_extra_specs_from_share(share):
    type_id = share.get('share_type_id', None)
    return get_share_type_extra_specs(type_id)

def parse_boolean_extra_spec(extra_spec_key, extra_spec_value):
    """Parse extra spec values of the form '<is> True' or '<is> False'

    This method returns the boolean value of an extra spec value.  If
    the value does not conform to the standard boolean pattern, it raises
    an InvalidExtraSpec exception.
    """

    try:
        if not isinstance(extra_spec_value, six.string_types):
            raise ValueError

        match = re.match(r'^<is>\s*(?P<value>True|False)$',
                         extra_spec_value.strip(),
                         re.IGNORECASE)
        if not match:
            raise ValueError
        else:
            return strutils.bool_from_string(match.group('value'), strict=True)
    except ValueError:
        msg = (_('Invalid boolean extra spec %(key)s : %(value)s') %
               {'key': extra_spec_key, 'value': extra_spec_value})
        raise exception.InvalidExtraSpec(reason=msg)


text:
<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
  <entity name="Prestamo" table="Prestamo">
    <indexes>
      <index name="fk_Presta_idx" columns="idPresta"/>
      <index name="fk_Recibe_idx" columns="idRecibe"/>
      <index name="fk_Equipo_idx" columns="idEquipo"/>
    </indexes>
    <id name="idprestamo" type="integer" column="idPrestamo">
      <generator strategy="IDENTITY"/>
    </id>
    <field name="fechaprestamo" type="date" column="fechaPrestamo" nullable="true"/>
    <field name="fechadevolucion" type="date" column="fechaDevolucion" nullable="true"/>
    <field name="descripcion" type="text" column="descripcion" length="65535" nullable="true"/>
    <many-to-one field="idrecibe" target-entity="Usuario">
      <join-columns>
        <join-column name="idRecibe" referenced-column-name="idUsuario"/>
      </join-columns>
    </many-to-one>
    <many-to-one field="idpresta" target-entity="Usuario">
      <join-columns>
        <join-column name="idPresta" referenced-column-name="idUsuario"/>
      </join-columns>
    </many-to-one>
    <many-to-one field="idequipo" target-entity="Equipo">
      <join-columns>
        <join-column name="idEquipo" referenced-column-name="idEquipo"/>
      </join-columns>
    </many-to-one>
  </entity>
</doctrine-mapping>


text:
'use strict'

export default ($scope, firebaseFactory) => {
    let tests = firebaseFactory.tests()
    $scope.tests = tests
    $scope.addTest = () => {
        let newTest = $scope.newTest
        $scope.tests.$add(newTest)
            .then((ref) => {
                $scope.newTest = ''
            })
    }
}