001/*
002 * (C) Copyright 2006-2012 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Thomas Roger <troger@nuxeo.com>
018 */
019package org.nuxeo.ecm.mobile.webengine.adapter;
020
021import java.util.ArrayList;
022import java.util.Collections;
023import java.util.HashMap;
024import java.util.List;
025import java.util.Map;
026
027import javax.ws.rs.GET;
028
029import org.nuxeo.ecm.core.api.CoreSession;
030import org.nuxeo.ecm.core.api.DocumentModel;
031import org.nuxeo.ecm.directory.Session;
032import org.nuxeo.ecm.directory.api.DirectoryService;
033import org.nuxeo.ecm.mobile.webengine.document.MobileDocument;
034import org.nuxeo.ecm.platform.relations.api.Node;
035import org.nuxeo.ecm.platform.relations.api.QNameResource;
036import org.nuxeo.ecm.platform.relations.api.RelationManager;
037import org.nuxeo.ecm.platform.relations.api.Resource;
038import org.nuxeo.ecm.platform.relations.api.ResourceAdapter;
039import org.nuxeo.ecm.platform.relations.api.Statement;
040import org.nuxeo.ecm.platform.relations.api.Subject;
041import org.nuxeo.ecm.platform.relations.api.impl.StatementImpl;
042import org.nuxeo.ecm.platform.relations.api.util.RelationConstants;
043import org.nuxeo.ecm.platform.relations.web.NodeInfo;
044import org.nuxeo.ecm.platform.relations.web.NodeInfoImpl;
045import org.nuxeo.ecm.platform.relations.web.StatementInfo;
046import org.nuxeo.ecm.platform.relations.web.StatementInfoImpl;
047import org.nuxeo.ecm.webengine.WebEngine;
048import org.nuxeo.ecm.webengine.WebException;
049import org.nuxeo.ecm.webengine.model.WebAdapter;
050import org.nuxeo.runtime.api.Framework;
051
052/**
053 * Adapter to retrieve annotations for the current {@code MobileDocument}.
054 * <p>
055 * Most of the code comes from the {@link org.nuxeo.ecm.platform.relations.web.listener.ejb.RelationActionsBean} class.
056 *
057 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a>
058 * @author <a href="mailto:bjalon@nuxeo.com">Benjamin JALON</a>
059 * @since 5.5
060 */
061@WebAdapter(name = "relation", type = "Relation", targetType = "MobileDocument")
062public class RelationAdapter extends DefaultMobileAdapter {
063
064    public static final String PREDICATES_DIRECTORY = "predicates";
065
066    @GET
067    public Object doGet() {
068        return getView("index");
069    }
070
071    public Map<String, List<StatementInfo>> getRelations() {
072        DocumentModel doc = getDocumentModel();
073        RelationManager relationManager = Framework.getLocalService(RelationManager.class);
074        Resource docResource = getDocumentResource(doc);
075
076        List<StatementInfo> allStatements = new ArrayList<StatementInfo>();
077        if (docResource != null) {
078            Statement pattern = new StatementImpl(docResource, null, null);
079            List<Statement> outgoingStatements = relationManager.getStatements(RelationConstants.GRAPH_NAME, pattern);
080            allStatements.addAll(getStatementsInfo(outgoingStatements));
081
082            pattern = new StatementImpl(null, null, docResource);
083            List<Statement> incomingStatements = relationManager.getStatements(RelationConstants.GRAPH_NAME, pattern);
084            allStatements.addAll(getStatementsInfo(incomingStatements));
085        }
086
087        Map<String, List<StatementInfo>> relations = new HashMap<String, List<StatementInfo>>();
088        for (StatementInfo statement : allStatements) {
089            String label = getPredicateLabel(PREDICATES_DIRECTORY, statement);
090            if (!relations.containsKey(label)) {
091                relations.put(label, new ArrayList<StatementInfo>());
092            }
093            List<StatementInfo> statements = relations.get(label);
094            statements.add(statement);
095            relations.put(label, statements);
096        }
097        return relations;
098    }
099
100    public boolean hasRelation() {
101        Map<String, List<StatementInfo>> relation = getRelations();
102        for (String key : relation.keySet()) {
103            if (relation.get(key).size() > 0) {
104                return true;
105            }
106        }
107        return false;
108    }
109
110    private QNameResource getDocumentResource(DocumentModel document) {
111        QNameResource documentResource = null;
112        if (document != null) {
113            documentResource = (QNameResource) Framework.getLocalService(RelationManager.class).getResource(
114                    RelationConstants.DOCUMENT_NAMESPACE, document, null);
115        }
116        return documentResource;
117    }
118
119    private List<StatementInfo> getStatementsInfo(List<Statement> statements) {
120        if (statements == null) {
121            return null;
122        }
123        List<StatementInfo> infoList = new ArrayList<StatementInfo>();
124        for (Statement statement : statements) {
125            Subject subject = statement.getSubject();
126            NodeInfo subjectInfo = new NodeInfoImpl(subject, getDocumentModel(subject), true);
127            Resource predicate = statement.getPredicate();
128            Node object = statement.getObject();
129            NodeInfo objectInfo = new NodeInfoImpl(object, getDocumentModel(object), true);
130            StatementInfo info = new StatementInfoImpl(statement, subjectInfo, new NodeInfoImpl(predicate), objectInfo);
131            infoList.add(info);
132        }
133        return infoList;
134    }
135
136    private DocumentModel getDocumentModel(Node node) {
137        if (node.isQNameResource()) {
138            QNameResource resource = (QNameResource) node;
139            CoreSession session = WebEngine.getActiveContext().getCoreSession();
140            Map<String, Object> context = Collections.<String, Object> singletonMap(
141                    ResourceAdapter.CORE_SESSION_CONTEXT_KEY, session);
142            Object o = Framework.getLocalService(RelationManager.class).getResourceRepresentation(
143                    resource.getNamespace(), resource, context);
144            if (o instanceof DocumentModel) {
145                return (DocumentModel) o;
146            }
147        }
148        return null;
149    }
150
151    /**
152     * Returns the predicate's label for a given {@code Statement}.
153     */
154    private String getPredicateLabel(String directoryName, StatementInfo statementInfo) {
155        DirectoryService directoryService = Framework.getLocalService(DirectoryService.class);
156        Session session = directoryService.open(directoryName);
157
158        DocumentModel entry = session.getEntry(statementInfo.getPredicate().getUri());
159        return (String) entry.getPropertyValue("vocabulary:label");
160    }
161
162}