001/**
002 * Copyright 2014 DuraSpace, Inc.
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 */
016package org.fcrepo.kernel.impl.rdf.impl;
017
018import static com.google.common.collect.ImmutableSet.builder;
019import static com.hp.hpl.jena.graph.NodeFactory.createLiteral;
020import static com.hp.hpl.jena.graph.NodeFactory.createURI;
021import static com.hp.hpl.jena.graph.Triple.create;
022import static com.hp.hpl.jena.rdf.model.ResourceFactory.createTypedLiteral;
023import static org.fcrepo.kernel.FedoraJcrTypes.ROOT;
024import static org.fcrepo.kernel.RdfLexicon.HAS_FIXITY_CHECK_COUNT;
025import static org.fcrepo.kernel.RdfLexicon.HAS_FIXITY_ERROR_COUNT;
026import static org.fcrepo.kernel.RdfLexicon.HAS_FIXITY_REPAIRED_COUNT;
027import static org.fcrepo.kernel.RdfLexicon.HAS_NODE_TYPE;
028import static org.fcrepo.kernel.RdfLexicon.REPOSITORY_NAMESPACE;
029import static org.slf4j.LoggerFactory.getLogger;
030
031import com.hp.hpl.jena.rdf.model.Resource;
032import org.fcrepo.kernel.models.FedoraResource;
033import org.fcrepo.kernel.identifiers.IdentifierConverter;
034import org.fcrepo.metrics.RegistryService;
035
036import java.util.Map;
037import java.util.SortedMap;
038
039import javax.jcr.Repository;
040import javax.jcr.RepositoryException;
041import javax.jcr.nodetype.NodeType;
042import javax.jcr.nodetype.NodeTypeIterator;
043import javax.jcr.nodetype.NodeTypeManager;
044
045import org.fcrepo.kernel.impl.services.functions.GetClusterConfiguration;
046import org.modeshape.jcr.JcrRepository;
047import org.slf4j.Logger;
048
049import com.codahale.metrics.Counter;
050import com.google.common.collect.ImmutableSet;
051import com.hp.hpl.jena.graph.Triple;
052
053/**
054 * Assemble {@link Triple}s derived from the root of a repository.
055 *
056 * @author ajs6f
057 * @since Oct 18, 2013
058 */
059public class RootRdfContext extends NodeRdfContext {
060
061    private static final Logger LOGGER = getLogger(RootRdfContext.class);
062    static final RegistryService registryService = RegistryService.getInstance();
063
064    /**
065     * Ordinary constructor.
066     *
067     * @param resource
068     * @param idTranslator
069     * @throws RepositoryException
070     */
071    public RootRdfContext(final FedoraResource resource,
072                          final IdentifierConverter<Resource, FedoraResource> idTranslator)
073            throws RepositoryException {
074        super(resource, idTranslator);
075
076        if (resource().hasType(ROOT)) {
077            concatRepositoryTriples();
078        }
079    }
080
081    private void concatRepositoryTriples() throws RepositoryException {
082        LOGGER.trace("Creating RDF triples for repository description");
083        final Repository repository = resource().getNode().getSession().getRepository();
084
085        final ImmutableSet.Builder<Triple> b = builder();
086
087        for (final String key : repository.getDescriptorKeys()) {
088            final String descriptor = repository.getDescriptor(key);
089            if (descriptor != null) {
090                final String uri = REPOSITORY_NAMESPACE + "repository." + key;
091                b.add(create(subject(), createURI(uri),
092                        createLiteral(descriptor)));
093            }
094        }
095        final NodeTypeManager nodeTypeManager =
096            resource().getNode().getSession().getWorkspace().getNodeTypeManager();
097
098        final NodeTypeIterator nodeTypes = nodeTypeManager.getAllNodeTypes();
099        while (nodeTypes.hasNext()) {
100            final NodeType nodeType = nodeTypes.nextNodeType();
101            b.add(create(subject(), HAS_NODE_TYPE.asNode(),
102                    createLiteral(nodeType.getName())));
103        }
104
105            /*
106                FIXME: removing because performance problems, esp. w/ many files on federated filesystem
107                see: https://www.pivotaltracker.com/story/show/78647248
108
109            b.add(create(subject(), HAS_OBJECT_COUNT.asNode(), createLiteral(String
110                    .valueOf(getRepositoryCount(repository)))));
111            b.add(create(subject(), HAS_OBJECT_SIZE.asNode(), createLiteral(String
112                    .valueOf(getRepositorySize(repository)))));
113            */
114
115        // Get the cluster configuration, if available
116        // this ugly test checks to see whether this is an ordinary JCR
117        // repository or a ModeShape repo, which will possess the extra info
118        if (JcrRepository.class.isAssignableFrom(repository.getClass())) {
119            final Map<String, String> config =
120                new GetClusterConfiguration().apply(repository);
121            assert (config != null);
122
123            for (final Map.Entry<String, String> entry : config.entrySet()) {
124                b.add(create(subject(), createURI(REPOSITORY_NAMESPACE + entry.getKey()),
125                        createLiteral(entry.getValue())));
126            }
127        }
128
129        // retrieve the metrics from the service
130        final SortedMap<String, Counter> counters = registryService.getMetrics().getCounters();
131        // and add the repository metrics to the RDF model
132        if (counters.containsKey("LowLevelStorageService.fixity-check-counter")) {
133            b.add(create(subject(), HAS_FIXITY_CHECK_COUNT.asNode(),
134                    createTypedLiteral(
135                            counters.get(
136                                    "org.fcrepo.services."
137                                            + "LowLevelStorageService."
138                                            + "fixity-check-counter")
139                                    .getCount()).asNode()));
140        }
141
142        if (counters.containsKey("LowLevelStorageService.fixity-error-counter")) {
143            b.add(create(subject(), HAS_FIXITY_ERROR_COUNT.asNode(),
144                    createTypedLiteral(
145                            counters.get(
146                                    "org.fcrepo.services."
147                                            + "LowLevelStorageService."
148                                            + "fixity-error-counter")
149                                    .getCount()).asNode()));
150        }
151
152        if (counters
153                .containsKey("LowLevelStorageService.fixity-repaired-counter")) {
154            b.add(create(subject(), HAS_FIXITY_REPAIRED_COUNT.asNode(),
155                    createTypedLiteral(
156                            counters.get(
157                                    "org.fcrepo.services."
158                                            + "LowLevelStorageService."
159                                            + "fixity-repaired-counter")
160                                    .getCount()).asNode()));
161        }
162
163        // offer all these accumulated triples
164        concat(b.build());
165    }
166
167}