001/**
002 * Copyright 2015 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.services;
017
018import static javax.jcr.query.Query.JCR_SQL2;
019import static org.fcrepo.kernel.FedoraJcrTypes.CONTENT_SIZE;
020import static org.fcrepo.kernel.FedoraJcrTypes.FEDORA_BINARY;
021import static org.fcrepo.kernel.FedoraJcrTypes.FEDORA_CONTAINER;
022import static org.modeshape.jcr.api.JcrConstants.JCR_CONTENT;
023import static org.modeshape.jcr.api.JcrConstants.JCR_DATA;
024import static org.modeshape.jcr.api.JcrConstants.JCR_PATH;
025import static org.modeshape.jcr.api.JcrConstants.NT_FILE;
026
027import javax.jcr.Node;
028import javax.jcr.NodeIterator;
029import javax.jcr.Property;
030import javax.jcr.PropertyIterator;
031import javax.jcr.Repository;
032import javax.jcr.RepositoryException;
033import javax.jcr.Session;
034import javax.jcr.Value;
035import javax.jcr.query.QueryManager;
036import javax.jcr.query.QueryResult;
037import javax.jcr.query.RowIterator;
038
039import org.fcrepo.kernel.exception.RepositoryRuntimeException;
040import org.springframework.stereotype.Component;
041
042/**
043 * Uncategorized helper methods
044 *
045 * @author awoods
046 */
047@Component
048public class ServiceHelpers {
049
050    private ServiceHelpers() {
051    }
052
053    /**
054     * Get the total size of a Node's properties
055     * 
056     * @param node the node
057     * @return size in bytes
058     * @throws RepositoryException if repository exception occurred
059     */
060    public static Long getNodePropertySize(final Node node)
061        throws RepositoryException {
062        Long size = 0L;
063        for (final PropertyIterator i = node.getProperties(); i.hasNext();) {
064            final Property p = i.nextProperty();
065            if (p.isMultiple()) {
066                for (final Value v : p.getValues()) {
067                    size += v.getBinary().getSize();
068                }
069            } else {
070                size += p.getBinary().getSize();
071            }
072        }
073        return size;
074    }
075
076    /**
077     * @param obj the object
078     * @return object size in bytes
079     * @throws RepositoryException if repository exception occurred
080     */
081    public static Long getObjectSize(final Node obj) throws RepositoryException {
082        return getNodePropertySize(obj) + getObjectDSSize(obj);
083    }
084
085    /**
086     * @param obj the object
087     * @return object's datastreams' total size in bytes
088     * @throws RepositoryException if repository exception occurred
089     */
090    private static Long getObjectDSSize(final Node obj)
091        throws RepositoryException {
092        Long size = 0L;
093        for (final NodeIterator i = obj.getNodes(); i.hasNext();) {
094            final Node node = i.nextNode();
095            if (node.isNodeType(NT_FILE)) {
096                size += getDatastreamSize(node);
097            }
098        }
099        return size;
100    }
101
102    /**
103     * Get the size of a datastream by calculating the size of the properties
104     * and the binary properties
105     * 
106     * @param ds the node
107     * @return size of the datastream's properties and binary properties
108     * @throws RepositoryException if repository exception occurred
109     */
110    public static Long getDatastreamSize(final Node ds)
111        throws RepositoryException {
112        return getNodePropertySize(ds) + getContentSize(ds);
113    }
114
115    /**
116     * Get the size of the JCR content binary property
117     * 
118     * @param ds the given node
119     * @return size of the binary content property
120     */
121    public static Long getContentSize(final Node ds) {
122        try {
123            long size = 0L;
124            if (ds.hasNode(JCR_CONTENT)) {
125                final Node contentNode = ds.getNode(JCR_CONTENT);
126
127                if (contentNode.hasProperty(JCR_DATA)) {
128                    size =
129                            ds.getNode(JCR_CONTENT).getProperty(JCR_DATA)
130                                    .getBinary().getSize();
131                }
132            }
133
134            return size;
135
136        } catch (final RepositoryException e) {
137            throw new RepositoryRuntimeException(e);
138        }
139    }
140
141    /**
142     * @param repository the repository
143     * @return a double of the size of the fedora:datastream binary content
144     * @throws RepositoryException if repository exception occurred
145     */
146    public static long getRepositoryCount(final Repository repository)
147        throws RepositoryException {
148        final Session session = repository.login();
149        try {
150            final QueryManager queryManager =
151                session.getWorkspace().getQueryManager();
152
153            final String querystring =
154                "SELECT [" + JCR_PATH + "] FROM ["
155                        + FEDORA_CONTAINER + "]";
156
157            final QueryResult queryResults =
158                queryManager.createQuery(querystring, JCR_SQL2).execute();
159
160            return queryResults.getRows().getSize();
161        } finally {
162            session.logout();
163        }
164    }
165
166    /**
167     * @param repository the repository
168     * @return a double of the size of the fedora:datastream binary content
169     * @throws RepositoryException if repository exception occurred
170     */
171    public static long getRepositorySize(final Repository repository)
172        throws RepositoryException {
173        final Session session = repository.login();
174        try {
175            long sum = 0;
176            final QueryManager queryManager =
177                    session.getWorkspace().getQueryManager();
178
179            final String querystring =
180                    "SELECT [" + CONTENT_SIZE + "] FROM [" +
181                            FEDORA_BINARY + "]";
182
183            final QueryResult queryResults =
184                    queryManager.createQuery(querystring, JCR_SQL2).execute();
185
186            for (final RowIterator rows = queryResults.getRows(); rows.hasNext(); ) {
187                final Value value =
188                        rows.nextRow().getValue(CONTENT_SIZE);
189                sum += value.getLong();
190            }
191            return sum;
192        } finally {
193            session.logout();
194        }
195    }
196
197}