001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     bstefanescu
011 */
012package org.nuxeo.ecm.automation.core.operations.services;
013
014import java.util.Collections;
015import java.util.List;
016import java.util.Map;
017
018import org.apache.commons.lang.StringUtils;
019import org.nuxeo.ecm.automation.core.Constants;
020import org.nuxeo.ecm.automation.core.annotations.Context;
021import org.nuxeo.ecm.automation.core.annotations.Operation;
022import org.nuxeo.ecm.automation.core.annotations.OperationMethod;
023import org.nuxeo.ecm.automation.core.annotations.Param;
024import org.nuxeo.ecm.core.api.CoreSession;
025import org.nuxeo.ecm.core.api.DocumentModel;
026import org.nuxeo.ecm.core.api.DocumentModelList;
027import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl;
028import org.nuxeo.ecm.platform.relations.api.Node;
029import org.nuxeo.ecm.platform.relations.api.QNameResource;
030import org.nuxeo.ecm.platform.relations.api.RelationManager;
031import org.nuxeo.ecm.platform.relations.api.Resource;
032import org.nuxeo.ecm.platform.relations.api.ResourceAdapter;
033import org.nuxeo.ecm.platform.relations.api.Statement;
034import org.nuxeo.ecm.platform.relations.api.impl.ResourceImpl;
035import org.nuxeo.ecm.platform.relations.api.util.RelationConstants;
036
037/**
038 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
039 */
040@Operation(id = GetRelations.ID, category = Constants.CAT_SERVICES, label = "Get Linked Documents", description = "Get the relations for the input document. The 'outgoing' parameter ca be used to specify whether outgoing or incoming relations should be returned. Retuns a document list.", aliases = { "Relations.GetRelations" })
041public class GetRelations {
042
043    public static final String ID = "Document.GetLinkedDocuments";
044
045    @Context
046    protected CoreSession session;
047
048    @Context
049    protected RelationManager relations;
050
051    @Param(name = "predicate")
052    // TODO use a combo box?
053    protected String predicate;
054
055    @Param(name = "outgoing", required = false)
056    protected boolean outgoing = true;
057
058    @Param(name = "graphName", required = false)
059    protected String graphName;
060
061    @OperationMethod
062    public DocumentModelList run(DocumentModel doc) {
063        QNameResource res = getDocumentResource(doc);
064        Resource predicate = getPredicate();
065        return getDocuments(res, predicate);
066    }
067
068    protected QNameResource getDocumentResource(DocumentModel document) {
069        return (QNameResource) relations.getResource(RelationConstants.DOCUMENT_NAMESPACE, document, null);
070    }
071
072    protected Resource getPredicate() {
073        return predicate != null && predicate.length() > 0 ? new ResourceImpl(predicate) : null;
074    }
075
076    protected DocumentModelList getDocuments(QNameResource res, Resource predicate) {
077        if (outgoing) {
078            List<Statement> statements = getOutgoingStatements(res, predicate);
079            DocumentModelList docs = new DocumentModelListImpl(statements.size());
080            for (Statement st : statements) {
081                DocumentModel dm = getDocumentModel(st.getObject());
082                if (dm != null) {
083                    docs.add(dm);
084                }
085            }
086            return docs;
087        } else {
088            List<Statement> statements = getIncomingStatements(res, predicate);
089            DocumentModelList docs = new DocumentModelListImpl(statements.size());
090            for (Statement st : statements) {
091                DocumentModel dm = getDocumentModel(st.getSubject());
092                if (dm != null) {
093                    docs.add(dm);
094                }
095            }
096            return docs;
097        }
098    }
099
100    protected List<Statement> getIncomingStatements(QNameResource res, Resource predicate) {
101        return relations.getGraphByName(getGraphName()).getStatements(null, predicate, res);
102    }
103
104    protected List<Statement> getOutgoingStatements(QNameResource res, Resource predicate) {
105        return relations.getGraphByName(getGraphName()).getStatements(res, predicate, null);
106    }
107
108    protected DocumentModel getDocumentModel(Node node) {
109        if (node.isQNameResource()) {
110            QNameResource resource = (QNameResource) node;
111            Map<String, Object> context = Collections.<String, Object> singletonMap(
112                    ResourceAdapter.CORE_SESSION_CONTEXT_KEY, session);
113            Object o = relations.getResourceRepresentation(resource.getNamespace(), resource, context);
114            if (o instanceof DocumentModel) {
115                return (DocumentModel) o;
116            }
117        }
118        return null;
119    }
120
121    /**
122     * @since 5.5
123     */
124    public String getGraphName() {
125        if (StringUtils.isEmpty(graphName)) {
126            return RelationConstants.GRAPH_NAME;
127        }
128        return graphName;
129    }
130
131}