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