001/*
002 * Licensed to DuraSpace under one or more contributor license agreements.
003 * See the NOTICE file distributed with this work for additional information
004 * regarding copyright ownership.
005 *
006 * DuraSpace licenses this file to you under the Apache License,
007 * Version 2.0 (the "License"); you may not use this file except in
008 * compliance with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.fcrepo.kernel.modeshape.services;
019
020import static javax.jcr.query.Query.JCR_SQL2;
021import static org.fcrepo.kernel.api.FedoraTypes.CONTENT_SIZE;
022import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_BINARY;
023import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_CONTAINER;
024import static org.modeshape.jcr.api.JcrConstants.JCR_CONTENT;
025import static org.modeshape.jcr.api.JcrConstants.JCR_DATA;
026import static org.modeshape.jcr.api.JcrConstants.JCR_PATH;
027import static org.modeshape.jcr.api.JcrConstants.NT_FILE;
028
029import javax.jcr.Node;
030import javax.jcr.NodeIterator;
031import javax.jcr.Property;
032import javax.jcr.PropertyIterator;
033import javax.jcr.Repository;
034import javax.jcr.RepositoryException;
035import javax.jcr.Session;
036import javax.jcr.Value;
037import javax.jcr.query.QueryManager;
038import javax.jcr.query.QueryResult;
039import javax.jcr.query.RowIterator;
040
041import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
042import org.springframework.stereotype.Component;
043
044/**
045 * Uncategorized helper methods
046 *
047 * @author awoods
048 */
049@Component
050public class ServiceHelpers {
051
052    private ServiceHelpers() {
053    }
054
055    /**
056     * Get the total size of a Node's properties
057     * 
058     * @param node the node
059     * @return size in bytes
060     * @throws RepositoryException if repository exception occurred
061     */
062    public static Long getNodePropertySize(final Node node)
063        throws RepositoryException {
064        Long size = 0L;
065        for (final PropertyIterator i = node.getProperties(); i.hasNext();) {
066            final Property p = i.nextProperty();
067            if (p.isMultiple()) {
068                for (final Value v : p.getValues()) {
069                    size += v.getBinary().getSize();
070                }
071            } else {
072                size += p.getBinary().getSize();
073            }
074        }
075        return size;
076    }
077
078    /**
079     * @param obj the object
080     * @return object size in bytes
081     * @throws RepositoryException if repository exception occurred
082     */
083    public static Long getObjectSize(final Node obj) throws RepositoryException {
084        return getNodePropertySize(obj) + getObjectDSSize(obj);
085    }
086
087    /**
088     * @param obj the object
089     * @return object's datastreams' total size in bytes
090     * @throws RepositoryException if repository exception occurred
091     */
092    private static Long getObjectDSSize(final Node obj)
093        throws RepositoryException {
094        Long size = 0L;
095        for (final NodeIterator i = obj.getNodes(); i.hasNext();) {
096            final Node node = i.nextNode();
097            if (node.isNodeType(NT_FILE)) {
098                size += getDatastreamSize(node);
099            }
100        }
101        return size;
102    }
103
104    /**
105     * Get the size of a datastream by calculating the size of the properties
106     * and the binary properties
107     * 
108     * @param ds the node
109     * @return size of the datastream's properties and binary properties
110     * @throws RepositoryException if repository exception occurred
111     */
112    public static Long getDatastreamSize(final Node ds)
113        throws RepositoryException {
114        return getNodePropertySize(ds) + getContentSize(ds);
115    }
116
117    /**
118     * Get the size of the JCR content binary property
119     * 
120     * @param ds the given node
121     * @return size of the binary content property
122     */
123    public static Long getContentSize(final Node ds) {
124        try {
125            long size = 0L;
126            if (ds.hasNode(JCR_CONTENT)) {
127                final Node contentNode = ds.getNode(JCR_CONTENT);
128
129                if (contentNode.hasProperty(JCR_DATA)) {
130                    size =
131                            ds.getNode(JCR_CONTENT).getProperty(JCR_DATA)
132                                    .getBinary().getSize();
133                }
134            }
135
136            return size;
137
138        } catch (final RepositoryException e) {
139            throw new RepositoryRuntimeException(e);
140        }
141    }
142
143    /**
144     * @param repository the repository
145     * @return a double of the size of the fedora:datastream binary content
146     * @throws RepositoryException if repository exception occurred
147     */
148    public static long getRepositoryCount(final Repository repository)
149        throws RepositoryException {
150        final Session session = repository.login();
151        try {
152            final QueryManager queryManager =
153                session.getWorkspace().getQueryManager();
154
155            final String querystring =
156                "SELECT [" + JCR_PATH + "] FROM ["
157                        + FEDORA_CONTAINER + "]";
158
159            final QueryResult queryResults =
160                queryManager.createQuery(querystring, JCR_SQL2).execute();
161
162            return queryResults.getRows().getSize();
163        } finally {
164            session.logout();
165        }
166    }
167
168    /**
169     * @param repository the repository
170     * @return a double of the size of the fedora:datastream binary content
171     * @throws RepositoryException if repository exception occurred
172     */
173    public static long getRepositorySize(final Repository repository)
174        throws RepositoryException {
175        final Session session = repository.login();
176        try {
177            long sum = 0;
178            final QueryManager queryManager =
179                    session.getWorkspace().getQueryManager();
180
181            final String querystring =
182                    "SELECT [" + CONTENT_SIZE + "] FROM [" +
183                            FEDORA_BINARY + "]";
184
185            final QueryResult queryResults =
186                    queryManager.createQuery(querystring, JCR_SQL2).execute();
187
188            for (final RowIterator rows = queryResults.getRows(); rows.hasNext(); ) {
189                final Value value =
190                        rows.nextRow().getValue(CONTENT_SIZE);
191                sum += value.getLong();
192            }
193            return sum;
194        } finally {
195            session.logout();
196        }
197    }
198
199}