moving queries to DAOs

This commit is contained in:
Ondřej Košarko
2016-01-25 13:08:39 +01:00
parent b87cf2f723
commit ec804f81e2
47 changed files with 467 additions and 209 deletions

View File

@@ -401,6 +401,11 @@ public class BitstreamServiceImpl extends DSpaceObjectServiceImpl<Bitstream> imp
return bitstreamDAO.countByStoreNumber(context, storeNumber); return bitstreamDAO.countByStoreNumber(context, storeNumber);
} }
@Override
public int countTotal(Context context) throws SQLException {
return bitstreamDAO.countRows(context);
}
@Override @Override
public Bitstream findByIdOrLegacyId(Context context, String id) throws SQLException { public Bitstream findByIdOrLegacyId(Context context, String id) throws SQLException {
if(StringUtils.isNumeric(id)) if(StringUtils.isNumeric(id))
@@ -418,4 +423,19 @@ public class BitstreamServiceImpl extends DSpaceObjectServiceImpl<Bitstream> imp
return bitstreamDAO.findByLegacyId(context, id, Bitstream.class); return bitstreamDAO.findByLegacyId(context, id, Bitstream.class);
} }
@Override
public int countDeletedBitstreams(Context context) throws SQLException {
return bitstreamDAO.countDeleted(context);
}
@Override
public int countBitstreamsWithoutPolicy(Context context) throws SQLException {
return bitstreamDAO.countWithNoPolicy(context);
}
@Override
public List<Bitstream> getNotReferencedBitstreams(Context context) throws SQLException {
return bitstreamDAO.getNotReferencedBitstreams(context);
}
} }

View File

@@ -428,4 +428,9 @@ public class BundleServiceImpl extends DSpaceObjectServiceImpl<Bundle> implement
public Bundle findByLegacyId(Context context, int id) throws SQLException { public Bundle findByLegacyId(Context context, int id) throws SQLException {
return bundleDAO.findByLegacyId(context, id, Bundle.class); return bundleDAO.findByLegacyId(context, id, Bundle.class);
} }
@Override
public int countTotal(Context context) throws SQLException {
return bundleDAO.countRows(context);
}
} }

View File

@@ -762,6 +762,11 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
return collectionDAO.findByGroup(context, group); return collectionDAO.findByGroup(context, group);
} }
@Override
public List<Collection> findCollectionsWithSubscribers(Context context) throws SQLException {
return collectionDAO.findCollectionsWithSubscribers(context);
}
@Override @Override
public DSpaceObject getAdminObject(Context context, Collection collection, int action) throws SQLException { public DSpaceObject getAdminObject(Context context, Collection collection, int action) throws SQLException {
DSpaceObject adminObject = null; DSpaceObject adminObject = null;
@@ -831,4 +836,14 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
public Collection findByLegacyId(Context context, int id) throws SQLException { public Collection findByLegacyId(Context context, int id) throws SQLException {
return collectionDAO.findByLegacyId(context, id, Collection.class); return collectionDAO.findByLegacyId(context, id, Collection.class);
} }
@Override
public int countTotal(Context context) throws SQLException {
return collectionDAO.countRows(context);
}
@Override
public List<Map> getCollectionsWithBitstreamSizesTotal(Context context) throws SQLException {
return collectionDAO.getCollectionsWithBitstreamSizesTotal(context);
}
} }

View File

@@ -670,4 +670,9 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
public Community findByLegacyId(Context context, int id) throws SQLException { public Community findByLegacyId(Context context, int id) throws SQLException {
return communityDAO.findByLegacyId(context, id, Community.class); return communityDAO.findByLegacyId(context, id, Community.class);
} }
@Override
public int countTotal(Context context) throws SQLException {
return communityDAO.countRows(context);
}
} }

View File

@@ -1152,4 +1152,19 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
{ {
return itemDAO.findByLastModifiedSince(context, last); return itemDAO.findByLastModifiedSince(context, last);
} }
@Override
public int countTotal(Context context) throws SQLException {
return itemDAO.countRows(context);
}
@Override
public int getNotArchivedItemsCount(Context context) throws SQLException {
return itemDAO.countNotArchived(context);
}
@Override
public int countWithdrawnItems(Context context) throws SQLException {
return itemDAO.countWithdrawn(context);
}
} }

View File

@@ -110,4 +110,9 @@ public class MetadataValueServiceImpl implements MetadataValueService {
return metadataValueDAO.getMinimum(context, return metadataValueDAO.getMinimum(context,
metadataFieldId); metadataFieldId);
} }
@Override
public int countTotal(Context context) throws SQLException {
return metadataValueDAO.countRows(context);
}
} }

View File

@@ -26,6 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Service implementation for the WorkspaceItem object. * Service implementation for the WorkspaceItem object.
@@ -216,6 +217,16 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService {
itemService.delete(context, item); itemService.delete(context, item);
} }
@Override
public int countTotal(Context context) throws SQLException {
return workspaceItemDAO.countRows(context);
}
@Override
public List<Map> getStageReachedCounts(Context context) throws SQLException {
return workspaceItemDAO.getStageReachedCounts(context);
}
@Override @Override
public void deleteWrapper(Context context, WorkspaceItem workspaceItem) throws SQLException, AuthorizeException { public void deleteWrapper(Context context, WorkspaceItem workspaceItem) throws SQLException, AuthorizeException {
// Check authorisation. We check permissions on the enclosed item. // Check authorisation. We check permissions on the enclosed item.

View File

@@ -41,4 +41,12 @@ public interface BitstreamDAO extends DSpaceObjectLegacySupportDAO<Bitstream> {
public Iterator<Bitstream> findByStoreNumber(Context context, Integer storeNumber) throws SQLException; public Iterator<Bitstream> findByStoreNumber(Context context, Integer storeNumber) throws SQLException;
public Long countByStoreNumber(Context context, Integer storeNumber) throws SQLException; public Long countByStoreNumber(Context context, Integer storeNumber) throws SQLException;
int countRows(Context context) throws SQLException;
int countDeleted(Context context) throws SQLException;
int countWithNoPolicy(Context context) throws SQLException;
List<Bitstream> getNotReferencedBitstreams(Context context) throws SQLException;
} }

View File

@@ -8,6 +8,9 @@
package org.dspace.content.dao; package org.dspace.content.dao;
import org.dspace.content.Bundle; import org.dspace.content.Bundle;
import org.dspace.core.Context;
import java.sql.SQLException;
/** /**
* Database Access Object interface class for the Bundle object. * Database Access Object interface class for the Bundle object.
@@ -17,4 +20,5 @@ import org.dspace.content.Bundle;
* @author kevinvandevelde at atmire.com * @author kevinvandevelde at atmire.com
*/ */
public interface BundleDAO extends DSpaceObjectLegacySupportDAO<Bundle> { public interface BundleDAO extends DSpaceObjectLegacySupportDAO<Bundle> {
int countRows(Context context) throws SQLException;
} }

View File

@@ -16,6 +16,7 @@ import org.dspace.eperson.Group;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Database Access Object interface class for the Collection object. * Database Access Object interface class for the Collection object.
@@ -37,4 +38,10 @@ public interface CollectionDAO extends DSpaceObjectLegacySupportDAO<Collection>
public List<Collection> findAuthorized(Context context, EPerson ePerson, List<Integer> actions) throws SQLException; public List<Collection> findAuthorized(Context context, EPerson ePerson, List<Integer> actions) throws SQLException;
List<Collection> findAuthorizedByGroup(Context context, EPerson ePerson, List<Integer> actions) throws SQLException; List<Collection> findAuthorizedByGroup(Context context, EPerson ePerson, List<Integer> actions) throws SQLException;
List<Collection> findCollectionsWithSubscribers(Context context) throws SQLException;
int countRows(Context context) throws SQLException;
List<Map> getCollectionsWithBitstreamSizesTotal(Context context) throws SQLException;
} }

View File

@@ -36,4 +36,6 @@ public interface CommunityDAO extends DSpaceObjectLegacySupportDAO<Community> {
public List<Community> findAuthorized(Context context, EPerson ePerson, List<Integer> actions) throws SQLException; public List<Community> findAuthorized(Context context, EPerson ePerson, List<Integer> actions) throws SQLException;
public List<Community> findAuthorizedByGroup(Context context, EPerson currentUser, List<Integer> actions) throws SQLException; public List<Community> findAuthorizedByGroup(Context context, EPerson currentUser, List<Integer> actions) throws SQLException;
int countRows(Context context) throws SQLException;
} }

View File

@@ -70,4 +70,10 @@ public interface ItemDAO extends DSpaceObjectLegacySupportDAO<Item>
public Iterator<Item> findAll(Context context, boolean archived, public Iterator<Item> findAll(Context context, boolean archived,
boolean withdrawn, boolean discoverable, Date lastModified) boolean withdrawn, boolean discoverable, Date lastModified)
throws SQLException; throws SQLException;
int countRows(Context context) throws SQLException;
int countNotArchived(Context context) throws SQLException;
int countWithdrawn(Context context) throws SQLException;
} }

View File

@@ -32,4 +32,6 @@ public interface MetadataValueDAO extends GenericDAO<MetadataValue> {
public MetadataValue getMinimum(Context context, int metadataFieldId) public MetadataValue getMinimum(Context context, int metadataFieldId)
throws SQLException; throws SQLException;
int countRows(Context context) throws SQLException;
} }

View File

@@ -16,6 +16,7 @@ import org.dspace.eperson.EPerson;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Database Access Object interface class for the WorkspaceItem object. * Database Access Object interface class for the WorkspaceItem object.
@@ -37,4 +38,8 @@ public interface WorkspaceItemDAO extends GenericDAO<WorkspaceItem> {
public List<WorkspaceItem> findWithSupervisedGroup(Context context) throws SQLException; public List<WorkspaceItem> findWithSupervisedGroup(Context context) throws SQLException;
public List<WorkspaceItem> findBySupervisedGroupMember(Context context, EPerson ePerson) throws SQLException; public List<WorkspaceItem> findBySupervisedGroupMember(Context context, EPerson ePerson) throws SQLException;
int countRows(Context context) throws SQLException;
List<Map> getStageReachedCounts(Context context) throws SQLException;
} }

View File

@@ -13,6 +13,7 @@ import org.dspace.content.Community;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.content.dao.BitstreamDAO; import org.dspace.content.dao.BitstreamDAO;
import org.dspace.core.AbstractHibernateDSODAO; import org.dspace.core.AbstractHibernateDSODAO;
import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.hibernate.Criteria; import org.hibernate.Criteria;
import org.hibernate.Query; import org.hibernate.Query;
@@ -119,4 +120,31 @@ public class BitstreamDAOImpl extends AbstractHibernateDSODAO<Bitstream> impleme
criteria.add(Restrictions.eq("storeNumber", storeNumber)); criteria.add(Restrictions.eq("storeNumber", storeNumber));
return countLong(criteria); return countLong(criteria);
} }
@Override
public int countRows(Context context) throws SQLException {
return count(createQuery(context, "SELECT count(*) from Bitstream"));
}
@Override
public int countDeleted(Context context) throws SQLException {
return count(createQuery(context, "SELECT count(*) FROM Bitstream b WHERE b.deleted=true"));
}
@Override
public int countWithNoPolicy(Context context) throws SQLException {
Query query = createQuery(context,"SELECT count(bit.id) from Bitstream bit where bit.deleted<>true and bit.id not in" +
" (select res.dSpaceObject from ResourcePolicy res where res.resourceTypeId = :typeId )" );
query.setParameter("typeId", Constants.BITSTREAM);
return count(query);
}
@Override
public List<Bitstream> getNotReferencedBitstreams(Context context) throws SQLException {
return list(createQuery(context,"select bit from Bitstream bit where bit.deleted != true" +
" and bit.id not in (select bit2.id from Bundle bun join bun.bitstreams bit2)" +
" and bit.id not in (select com.logo.id from Community com)" +
" and bit.id not in (select col.logo.id from Collection col)" +
" and bit.id not in (select bun.primaryBitstream.id from Bundle bun)"));
}
} }

View File

@@ -10,6 +10,9 @@ package org.dspace.content.dao.impl;
import org.dspace.content.Bundle; import org.dspace.content.Bundle;
import org.dspace.content.dao.BundleDAO; import org.dspace.content.dao.BundleDAO;
import org.dspace.core.AbstractHibernateDSODAO; import org.dspace.core.AbstractHibernateDSODAO;
import org.dspace.core.Context;
import java.sql.SQLException;
/** /**
* Hibernate implementation of the Database Access Object interface class for the Bundle object. * Hibernate implementation of the Database Access Object interface class for the Bundle object.
@@ -21,5 +24,8 @@ import org.dspace.core.AbstractHibernateDSODAO;
public class BundleDAOImpl extends AbstractHibernateDSODAO<Bundle> implements BundleDAO { public class BundleDAOImpl extends AbstractHibernateDSODAO<Bundle> implements BundleDAO {
@Override
public int countRows(Context context) throws SQLException {
return count(createQuery(context, "SELECT count(*) from Bundle"));
}
} }

View File

@@ -20,10 +20,12 @@ import org.hibernate.Criteria;
import org.hibernate.Query; import org.hibernate.Query;
import org.hibernate.criterion.Disjunction; import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Hibernate implementation of the Database Access Object interface class for the Collection object. * Hibernate implementation of the Database Access Object interface class for the Collection object.
@@ -158,6 +160,19 @@ public class CollectionDAOImpl extends AbstractHibernateDSODAO<Collection> imple
} }
@Override
public List<Collection> findCollectionsWithSubscribers(Context context) throws SQLException {
return list(createQuery(context, "SELECT DISTINCT col FROM Subscription s join s.collection col"));
}
@Override
public int countRows(Context context) throws SQLException {
return count(createQuery(context, "SELECT count(*) FROM Collection"));
}
@Override
public List<Map> getCollectionsWithBitstreamSizesTotal(Context context) throws SQLException {
String q = "select col as collection, sum(bit.sizeBytes) as totalBytes from Item i join i.collections col join i.bundles bun join bun.bitstreams bit group by col";
return createQuery(context, q).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
}
} }

View File

@@ -160,4 +160,9 @@ public class CommunityDAOImpl extends AbstractHibernateDSODAO<Community> impleme
hibernateQuery.setParameter("eperson_id", ePerson.getID()); hibernateQuery.setParameter("eperson_id", ePerson.getID());
return list(hibernateQuery); return list(hibernateQuery);
} }
@Override
public int countRows(Context context) throws SQLException {
return count(createQuery(context, "SELECT count(*) FROM Community"));
}
} }

View File

@@ -246,4 +246,19 @@ public class ItemDAOImpl extends AbstractHibernateDSODAO<Item> implements ItemDA
query.setTimestamp("last_modified", since); query.setTimestamp("last_modified", since);
return iterate(query); return iterate(query);
} }
@Override
public int countRows(Context context) throws SQLException {
return count(createQuery(context, "SELECT count(*) FROM Item"));
}
@Override
public int countNotArchived(Context context) throws SQLException {
return count(createQuery(context, "SELECT count(*) FROM Item i WHERE i.inArchive=false AND i.withdrawn=false"));
}
@Override
public int countWithdrawn(Context context) throws SQLException {
return count(createQuery(context, "SELECT count(*) FROM Item i WHERE i.withdrawn=true"));
}
} }

View File

@@ -66,4 +66,9 @@ public class MetadataValueDAOImpl extends AbstractHibernateDAO<MetadataValue> im
query.setMaxResults(1); query.setMaxResults(1);
return (MetadataValue) query.uniqueResult(); return (MetadataValue) query.uniqueResult();
} }
@Override
public int countRows(Context context) throws SQLException {
return count(createQuery(context, "SELECT count(*) FROM MetadataValue"));
}
} }

View File

@@ -18,9 +18,11 @@ import org.hibernate.Criteria;
import org.hibernate.Query; import org.hibernate.Query;
import org.hibernate.criterion.Order; import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Hibernate implementation of the Database Access Object interface class for the WorkspaceItem object. * Hibernate implementation of the Database Access Object interface class for the WorkspaceItem object.
@@ -82,4 +84,16 @@ public class WorkspaceItemDAOImpl extends AbstractHibernateDAO<WorkspaceItem> im
return list(criteria); return list(criteria);
} }
@Override
public int countRows(Context context) throws SQLException {
return count(createQuery(context, "SELECT count(*) from WorkspaceItem"));
}
@Override
public List<Map> getStageReachedCounts(Context context) throws SQLException {
return createQuery(context,"SELECT wi.stageReached as stage_reached, count(*) as cnt from WorkspaceItem wi" +
" group by wi.stageReached order by wi.stageReached").setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)
.list();
}
} }

View File

@@ -178,4 +178,12 @@ public interface BitstreamService extends DSpaceObjectService<Bitstream>, DSpace
public Iterator<Bitstream> findByStoreNumber(Context context, Integer storeNumber) throws SQLException; public Iterator<Bitstream> findByStoreNumber(Context context, Integer storeNumber) throws SQLException;
public Long countByStoreNumber(Context context, Integer storeNumber) throws SQLException; public Long countByStoreNumber(Context context, Integer storeNumber) throws SQLException;
int countTotal(Context context) throws SQLException ;
int countDeletedBitstreams(Context context) throws SQLException;
int countBitstreamsWithoutPolicy(Context context) throws SQLException;
List<Bitstream> getNotReferencedBitstreams(Context context) throws SQLException;
} }

View File

@@ -105,4 +105,6 @@ public interface BundleService extends DSpaceObjectService<Bundle>, DSpaceObject
* @throws AuthorizeException If the user can't make the changes * @throws AuthorizeException If the user can't make the changes
*/ */
public void setOrder(Context context, Bundle bundle, UUID bitstreamIds[]) throws AuthorizeException, SQLException; public void setOrder(Context context, Bundle bundle, UUID bitstreamIds[]) throws AuthorizeException, SQLException;
int countTotal(Context context) throws SQLException;
} }

View File

@@ -19,6 +19,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.MissingResourceException; import java.util.MissingResourceException;
/** /**
@@ -285,7 +286,7 @@ public interface CollectionService extends DSpaceObjectService<Collection>, DSpa
* collections a person is an editor for. * collections a person is an editor for.
* *
* @param context * @param context
* @param comm * @param community
* (optional) restrict search to a community, else null * (optional) restrict search to a community, else null
* @param actionID * @param actionID
* of the action * of the action
@@ -296,4 +297,10 @@ public interface CollectionService extends DSpaceObjectService<Collection>, DSpa
public List<Collection> findAuthorized(Context context, Community community, int actionID) throws java.sql.SQLException; public List<Collection> findAuthorized(Context context, Community community, int actionID) throws java.sql.SQLException;
public Collection findByGroup(Context context, Group group) throws SQLException; public Collection findByGroup(Context context, Group group) throws SQLException;
List<Collection> findCollectionsWithSubscribers(Context context) throws SQLException;
int countTotal(Context context) throws SQLException;
List<Map> getCollectionsWithBitstreamSizesTotal(Context context) throws SQLException;
} }

View File

@@ -255,4 +255,6 @@ public interface CommunityService extends DSpaceObjectService<Community>, DSpace
public List<Community> findAuthorized(Context context, List<Integer> actions) throws SQLException; public List<Community> findAuthorized(Context context, List<Integer> actions) throws SQLException;
public List<Community> findAuthorizedGroupMapped(Context context, List<Integer> actions) throws SQLException; public List<Community> findAuthorizedGroupMapped(Context context, List<Integer> actions) throws SQLException;
int countTotal(Context context) throws SQLException;
} }

View File

@@ -459,4 +459,10 @@ public interface ItemService extends DSpaceObjectService<Item>, DSpaceObjectLega
* @return total items * @return total items
*/ */
public int countItems(Context context, Community community) throws SQLException; public int countItems(Context context, Community community) throws SQLException;
int countTotal(Context context) throws SQLException;
int getNotArchivedItemsCount(Context context) throws SQLException;
int countWithdrawnItems(Context context) throws SQLException;
} }

View File

@@ -91,4 +91,6 @@ public interface MetadataValueService {
*/ */
public MetadataValue getMinimum(Context context, int metadataFieldId) public MetadataValue getMinimum(Context context, int metadataFieldId)
throws SQLException; throws SQLException;
int countTotal(Context context) throws SQLException;
} }

View File

@@ -18,6 +18,7 @@ import org.dspace.workflow.WorkflowItem;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Service interface class for the WorkspaceItem object. * Service interface class for the WorkspaceItem object.
@@ -124,4 +125,8 @@ public interface WorkspaceItemService extends InProgressSubmissionService<Worksp
* notwithstanding.) * notwithstanding.)
*/ */
public void deleteAll(Context context, WorkspaceItem workspaceItem) throws SQLException, AuthorizeException, IOException; public void deleteAll(Context context, WorkspaceItem workspaceItem) throws SQLException, AuthorizeException, IOException;
int countTotal(Context context) throws SQLException;
List<Map> getStageReachedCounts(Context context) throws SQLException;
} }

View File

@@ -367,6 +367,11 @@ public class EPersonServiceImpl extends DSpaceObjectServiceImpl<EPerson> impleme
} }
} }
@Override
public List<EPerson> findEPeopleWithSubscription(Context context) throws SQLException {
return ePersonDAO.findAllSubscribers(context);
}
@Override @Override
public void updateLastModified(Context context, EPerson dso) throws SQLException { public void updateLastModified(Context context, EPerson dso) throws SQLException {
//Not used //Not used
@@ -393,4 +398,9 @@ public class EPersonServiceImpl extends DSpaceObjectServiceImpl<EPerson> impleme
public List<EPerson> findNotActiveSince(Context context, Date date) throws SQLException { public List<EPerson> findNotActiveSince(Context context, Date date) throws SQLException {
return ePersonDAO.findNotActiveSince(context, date); return ePersonDAO.findNotActiveSince(context, date);
} }
@Override
public int countTotal(Context context) throws SQLException {
return ePersonDAO.countRows(context);
}
} }

View File

@@ -377,6 +377,11 @@ public class GroupServiceImpl extends DSpaceObjectServiceImpl<Group> implements
} }
} }
@Override
public List<Group> getEmptyGroups(Context context) throws SQLException {
return groupDAO.getEmptyGroups(context);
}
/** /**
* Update the group - writing out group object and EPerson list if necessary * Update the group - writing out group object and EPerson list if necessary
*/ */
@@ -607,4 +612,9 @@ public class GroupServiceImpl extends DSpaceObjectServiceImpl<Group> implements
public Group findByLegacyId(Context context, int id) throws SQLException { public Group findByLegacyId(Context context, int id) throws SQLException {
return groupDAO.findByLegacyId(context, id, Group.class); return groupDAO.findByLegacyId(context, id, Group.class);
} }
@Override
public int countTotal(Context context) throws SQLException {
return groupDAO.countRows(context);
}
} }

View File

@@ -43,4 +43,8 @@ public interface EPersonDAO extends DSpaceObjectDAO<EPerson>, DSpaceObjectLegacy
public List<EPerson> findNotActiveSince(Context context, Date date) throws SQLException; public List<EPerson> findNotActiveSince(Context context, Date date) throws SQLException;
public List<EPerson> findAll(Context context, MetadataField metadataFieldSort, String sortColumn) throws SQLException; public List<EPerson> findAll(Context context, MetadataField metadataFieldSort, String sortColumn) throws SQLException;
public List<EPerson> findAllSubscribers(Context context) throws SQLException;
int countRows(Context context) throws SQLException;
} }

View File

@@ -37,4 +37,8 @@ public interface GroupDAO extends DSpaceObjectDAO<Group>, DSpaceObjectLegacySupp
public List<Group> findByEPerson(Context context, EPerson ePerson) throws SQLException; public List<Group> findByEPerson(Context context, EPerson ePerson) throws SQLException;
public List getGroup2GroupResults(Context context, boolean flushQueries) throws SQLException; public List getGroup2GroupResults(Context context, boolean flushQueries) throws SQLException;
List<Group> getEmptyGroups(Context context) throws SQLException;
int countRows(Context context) throws SQLException;
} }

View File

@@ -145,4 +145,14 @@ public class EPersonDAOImpl extends AbstractHibernateDSODAO<EPerson> implements
return query; return query;
} }
@Override
public List<EPerson> findAllSubscribers(Context context) throws SQLException {
return list(createQuery(context, "SELECT DISTINCT e from Subscription s join s.ePerson e"));
}
@Override
public int countRows(Context context) throws SQLException {
return count(createQuery(context, "SELECT count(*) FROM EPerson"));
}
} }

View File

@@ -153,4 +153,13 @@ public class GroupDAOImpl extends AbstractHibernateDSODAO<Group> implements Grou
return sqlQuery.list(); return sqlQuery.list();
} }
@Override
public List<Group> getEmptyGroups(Context context) throws SQLException {
return list(createQuery(context, "SELECT g from Group g where g.epeople is EMPTY"));
}
@Override
public int countRows(Context context) throws SQLException {
return count(createQuery(context, "SELECT count(*) FROM Group"));
}
} }

View File

@@ -201,4 +201,8 @@ public interface EPersonService extends DSpaceObjectService<EPerson>, DSpaceObje
public List<String> getDeleteConstraints(Context context, EPerson ePerson) throws SQLException; public List<String> getDeleteConstraints(Context context, EPerson ePerson) throws SQLException;
public List<EPerson> findByGroups(Context c, Set<Group> groups) throws SQLException; public List<EPerson> findByGroups(Context c, Set<Group> groups) throws SQLException;
List<EPerson> findEPeopleWithSubscription(Context context) throws SQLException;
int countTotal(Context context) throws SQLException;
} }

View File

@@ -204,4 +204,8 @@ public interface GroupService extends DSpaceObjectService<Group>, DSpaceObjectLe
* @throws AuthorizeException * @throws AuthorizeException
*/ */
public void initDefaultGroupNames(Context context) throws SQLException, AuthorizeException; public void initDefaultGroupNames(Context context) throws SQLException, AuthorizeException;
List<Group> getEmptyGroups(Context context) throws SQLException;
int countTotal(Context context) throws SQLException;
} }

View File

@@ -399,4 +399,9 @@ public class HandleServiceImpl implements HandleService
return handlePrefix + (handlePrefix.endsWith("/") ? "" : "/") + id; return handlePrefix + (handlePrefix.endsWith("/") ? "" : "/") + id;
} }
@Override
public int countTotal(Context context) throws SQLException {
return handleDAO.countRows(context);
}
} }

View File

@@ -33,4 +33,6 @@ public interface HandleDAO extends GenericDAO<Handle> {
public long countHandlesByPrefix(Context context, String prefix) throws SQLException; public long countHandlesByPrefix(Context context, String prefix) throws SQLException;
int updateHandlesWithNewPrefix(Context context, String newPrefix, String oldPrefix) throws SQLException; int updateHandlesWithNewPrefix(Context context, String newPrefix, String oldPrefix) throws SQLException;
int countRows(Context context) throws SQLException;
} }

View File

@@ -67,4 +67,9 @@ public class HandleDAOImpl extends AbstractHibernateDAO<Handle> implements Handl
query.setString("oldPrefix", oldPrefix); query.setString("oldPrefix", oldPrefix);
return query.executeUpdate(); return query.executeUpdate();
} }
@Override
public int countRows(Context context) throws SQLException {
return count(createQuery(context, "SELECT count(*) FROM Handle"));
}
} }

View File

@@ -184,4 +184,6 @@ public interface HandleService {
public int updateHandlesWithNewPrefix(Context context, String newPrefix, String oldPrefix) throws SQLException; public int updateHandlesWithNewPrefix(Context context, String newPrefix, String oldPrefix) throws SQLException;
public void modifyHandleDSpaceObject(Context context, String handle, DSpaceObject newOwner) throws SQLException; public void modifyHandleDSpaceObject(Context context, String handle, DSpaceObject newOwner) throws SQLException;
int countTotal(Context context) throws SQLException;
} }

View File

@@ -1,185 +0,0 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.health;
import org.apache.commons.io.FileUtils;
import org.dspace.app.util.CollectionDropDown;
import org.dspace.content.*;
import org.dspace.content.Collection;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.*;
import org.dspace.core.AbstractHibernateDAO;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.eperson.Group;
import java.sql.SQLException;
import java.util.*;
/**
* @author LINDAT/CLARIN dev team
*/
public class Core {
private static AbstractHibernateDAO dao = new AbstractHibernateDAO<Object>(){};
private static ItemService itemService = ContentServiceFactory.getInstance().getItemService();
private static CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
private final Context context;
public Core(Context context){
this.context = context;
}
// get info
//
public String getCollectionSizesInfo() throws SQLException {
final StringBuffer ret = new StringBuffer();
List<Object[]> col_bitSizes = query("select col, sum(bit.sizeBytes) as sum from Item i join i.collections col join i.bundles bun join bun.bitstreams bit group by col");
long total_size = 0;
Collections.sort(col_bitSizes, new Comparator<Object[]>() {
@Override
public int compare(Object[] o1, Object[] o2) {
try {
return CollectionDropDown.collectionPath((Collection) o1[0]).compareTo(
CollectionDropDown.collectionPath((Collection) o2[0])
);
} catch (Exception e) {
ret.append(e.getMessage());
}
return 0;
}
});
for (Object[] row : col_bitSizes) {
Long size = (Long) row[1];
total_size += size;
Collection col = (Collection) row[0];
ret.append(String.format(
"\t%s: %s\n", CollectionDropDown.collectionPath(col), FileUtils.byteCountToDisplaySize((long) size)));
}
ret.append(String.format(
"Total size: %s\n", FileUtils.byteCountToDisplaySize(total_size)));
ret.append(String.format(
"Resource without policy: %d\n", getBitstreamsWithoutPolicyCount()));
ret.append(String.format(
"Deleted bitstreams: %d\n", getBitstreamsDeletedCount()));
String list_str = "";
List<UUID> bitstreamOrphans = getBitstreamOrphansRows();
for (UUID id : bitstreamOrphans) {
list_str += String.format("%d, ", id);
}
ret.append(String.format(
"Orphan bitstreams: %d [%s]\n", bitstreamOrphans.size(), list_str));
return ret.toString();
}
public String getObjectSizesInfo() throws SQLException {
String ret = "";
for (String tb : new String[] { "Bitstream", "Bundle", "Collection",
"Community", "MetadataValue", "EPerson", "Item", "Handle",
"Group", "BasicWorkflowItem", "WorkspaceItem", }) {
int count = count("SELECT COUNT(*) from " + tb);
ret += String.format("Count %-14s: %s\n", tb,
String.valueOf(count));
}
return ret;
}
// get objects
//
public List<Object[]> getWorkspaceItemsRows() throws SQLException {
return query("SELECT wi.stageReached, count(*) as cnt from WorkspaceItem wi group by wi.stageReached order by wi.stageReached");
}
public List<UUID> getBitstreamOrphansRows() throws SQLException {
return query("select bit.id from Bitstream bit where bit.deleted != true" +
" and bit.id not in (select bit2.id from Bundle bun join bun.bitstreams bit2)" +
" and bit.id not in (select com.logo.id from Community com)" +
" and bit.id not in (select col.logo.id from Collection col)" +
" and bit.id not in (select bun.primaryBitstream.id from Bundle bun)");
}
// get sizes
//
public int getWorkflowItemsCount() throws SQLException {
return count("SELECT count(*) FROM BasicWorkflowItem");
}
public int getNotArchivedItemsCount() throws SQLException {
return count(
"SELECT count(*) FROM Item i WHERE i.inArchive=false AND i.withdrawn=false");
}
public int getWithdrawnItemsCount() throws SQLException {
return count("SELECT count(*) FROM Item i WHERE i.withdrawn=true");
}
public int getBitstreamsWithoutPolicyCount() throws SQLException {
return count("SELECT count(bit.id) from Bitstream bit where bit.deleted<>true and bit.id not in" +
" (select res.dSpaceObject from ResourcePolicy res where res.resourceTypeId=" + Constants.BITSTREAM +")");
}
public int getBitstreamsDeletedCount() throws SQLException {
return count("SELECT count(*) FROM Bitstream b WHERE b.deleted=true");
}
// get more complex information
//
public List<Map.Entry<String, Integer>> getCommunities()
throws SQLException {
List<Map.Entry<String, Integer>> cl = new java.util.ArrayList<>();
List<Community> top_communities = communityService.findAllTop(context);
for (Community c : top_communities) {
cl.add(
new java.util.AbstractMap.SimpleEntry<>(c.getName(), itemService.countItems(context, c))
);
}
return cl;
}
public List<String> getEmptyGroups() throws SQLException {
List<String> ret = new ArrayList<>();
List<Group> emptyGroups = query("SELECT g from Group g where g.epeople is EMPTY");
for (Group group : emptyGroups) {
ret.add(String.format("id=%s;name=%s", group.getID(), group.getName() ));
}
return ret;
}
public List<UUID> getSubscribers() throws SQLException {
return query("SELECT DISTINCT e.id from Subscription s join s.ePerson e");
}
public List<UUID> getSubscribedCollections() throws SQLException {
return query("SELECT DISTINCT col.id FROM Subscription s join s.collection col");
}
//
//
int count(String query) throws SQLException {
return dao.count(dao.createQuery(context, query));
}
List query(String query) throws SQLException {
return dao.createQuery(context, query).list();
}
}

View File

@@ -8,24 +8,50 @@
package org.dspace.health; package org.dspace.health;
import org.apache.commons.io.FileUtils;
import org.dspace.app.util.CollectionDropDown;
import org.dspace.content.*;
import org.dspace.content.Collection;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.*;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.eperson.factory.EPersonServiceFactory;
import org.dspace.eperson.service.EPersonService;
import org.dspace.eperson.service.GroupService;
import org.dspace.handle.factory.HandleServiceFactory;
import org.dspace.handle.service.HandleService;
import org.dspace.workflowbasic.factory.BasicWorkflowServiceFactory;
import org.dspace.workflowbasic.service.BasicWorkflowItemService;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Map; import java.util.*;
/** /**
* @author LINDAT/CLARIN dev team * @author LINDAT/CLARIN dev team
*/ */
public class ItemCheck extends Check { public class ItemCheck extends Check {
private BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
private BundleService bundleService = ContentServiceFactory.getInstance().getBundleService();
private CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
private CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
private MetadataValueService metadataValueService = ContentServiceFactory.getInstance().getMetadataValueService();
private ItemService itemService = ContentServiceFactory.getInstance().getItemService();
private WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();
private BasicWorkflowItemService basicWorkflowItemService = BasicWorkflowServiceFactory.getInstance().getBasicWorkflowItemService();
private HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
private EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
private GroupService groupService = EPersonServiceFactory.getInstance().getGroupService();
@Override @Override
public String run( ReportInfo ri ) { public String run( ReportInfo ri ) {
String ret = ""; String ret = "";
int tot_cnt = 0; int tot_cnt = 0;
Context context = new Context(); Context context = new Context();
Core core = new Core(context);
try { try {
for (Map.Entry<String, Integer> name_count : core.getCommunities()) { for (Map.Entry<String, Integer> name_count : getCommunities(context)) {
ret += String.format("Community [%s]: %d\n", ret += String.format("Community [%s]: %d\n",
name_count.getKey(), name_count.getValue()); name_count.getKey(), name_count.getValue());
tot_cnt += name_count.getValue(); tot_cnt += name_count.getValue();
@@ -36,7 +62,7 @@ public class ItemCheck extends Check {
try { try {
ret += "\nCollection sizes:\n"; ret += "\nCollection sizes:\n";
ret += core.getCollectionSizesInfo(); ret += getCollectionSizesInfo(context);
} catch (SQLException e) { } catch (SQLException e) {
error(e); error(e);
} }
@@ -45,32 +71,119 @@ public class ItemCheck extends Check {
"\nPublished items (archived, not withdrawn): %d\n", tot_cnt); "\nPublished items (archived, not withdrawn): %d\n", tot_cnt);
try { try {
ret += String.format( ret += String.format(
"Withdrawn items: %d\n", core.getWithdrawnItemsCount()); "Withdrawn items: %d\n", itemService.countWithdrawnItems(context));
ret += String.format( ret += String.format(
"Not published items (in workspace or workflow mode): %d\n", "Not published items (in workspace or workflow mode): %d\n",
core.getNotArchivedItemsCount()); itemService.getNotArchivedItemsCount(context));
for (Object[] row : core.getWorkspaceItemsRows()) { for (Map row : workspaceItemService.getStageReachedCounts(context)) {
ret += String.format("\tIn Stage %s: %s\n", ret += String.format("\tIn Stage %s: %s\n",
row[0],// "stage_reached"), row.get("stage_reached"),
row[1]// "cnt") row.get("cnt")
); );
} }
ret += String.format( ret += String.format(
"\tWaiting for approval (workflow items): %d\n", "\tWaiting for approval (workflow items): %d\n",
core.getWorkflowItemsCount()); basicWorkflowItemService.countTotal(context));
} catch (SQLException e) { } catch (SQLException e) {
error(e); error(e);
} }
try { try {
ret += core.getObjectSizesInfo(); ret += getObjectSizesInfo(context);
context.complete(); context.complete();
} catch (SQLException e) { } catch (SQLException e) {
error(e); error(e);
} }
return ret; return ret;
} }
public String getObjectSizesInfo(Context context) throws SQLException {
StringBuilder sb = new StringBuilder();
sb.append(String.format("Count %-14s: %s\n", "Bitstream",
String.valueOf(bitstreamService.countTotal(context))));
sb.append(String.format("Count %-14s: %s\n", "Bundle",
String.valueOf(bundleService.countTotal(context))));
sb.append(String.format("Count %-14s: %s\n", "Collection",
String.valueOf(collectionService.countTotal(context))));
sb.append(String.format("Count %-14s: %s\n", "Community",
String.valueOf(communityService.countTotal(context))));
sb.append(String.format("Count %-14s: %s\n", "MetadataValue",
String.valueOf(metadataValueService.countTotal(context))));
sb.append(String.format("Count %-14s: %s\n", "EPerson",
String.valueOf(ePersonService.countTotal(context))));
sb.append(String.format("Count %-14s: %s\n", "Item",
String.valueOf(itemService.countTotal(context))));
sb.append(String.format("Count %-14s: %s\n", "Handle",
String.valueOf(handleService.countTotal(context))));
sb.append(String.format("Count %-14s: %s\n", "Group",
String.valueOf(groupService.countTotal(context))));
sb.append(String.format("Count %-14s: %s\n", "BasicWorkflowItem",
String.valueOf(basicWorkflowItemService.countTotal(context))));
sb.append(String.format("Count %-14s: %s\n", "WorkspaceItem",
String.valueOf(workspaceItemService.countTotal(context))));
return sb.toString();
}
public String getCollectionSizesInfo(Context context) throws SQLException {
final StringBuffer ret = new StringBuffer();
List<Map> colBitSizes = collectionService.getCollectionsWithBitstreamSizesTotal(context);
long total_size = 0;
Collections.sort(colBitSizes, new Comparator<Map>() {
@Override
public int compare(Map o1, Map o2) {
try {
return CollectionDropDown.collectionPath((Collection) o1.get("collection")).compareTo(
CollectionDropDown.collectionPath((Collection) o2.get("collection"))
);
} catch (Exception e) {
ret.append(e.getMessage());
}
return 0;
}
});
for (Map row : colBitSizes) {
Long size = (Long) row.get("totalBytes");
total_size += size;
Collection col = (Collection) row.get("collection");
ret.append(String.format(
"\t%s: %s\n", CollectionDropDown.collectionPath(col), FileUtils.byteCountToDisplaySize((long) size)));
}
ret.append(String.format(
"Total size: %s\n", FileUtils.byteCountToDisplaySize(total_size)));
ret.append(String.format(
"Resource without policy: %d\n", bitstreamService.countBitstreamsWithoutPolicy(context)));
ret.append(String.format(
"Deleted bitstreams: %d\n", bitstreamService.countDeletedBitstreams(context)));
String list_str = "";
List<Bitstream> bitstreamOrphans = bitstreamService.getNotReferencedBitstreams(context);
for (Bitstream orphan : bitstreamOrphans) {
UUID id = orphan.getID();
list_str += String.format("%d, ", id);
}
ret.append(String.format(
"Orphan bitstreams: %d [%s]\n", bitstreamOrphans.size(), list_str));
return ret.toString();
}
public List<Map.Entry<String, Integer>> getCommunities(Context context)
throws SQLException {
List<Map.Entry<String, Integer>> cl = new java.util.ArrayList<>();
List<Community> top_communities = communityService.findAllTop(context);
for (Community c : top_communities) {
cl.add(
new java.util.AbstractMap.SimpleEntry<>(c.getName(), itemService.countItems(context, c))
);
}
return cl;
}
} }

View File

@@ -8,17 +8,21 @@
package org.dspace.health; package org.dspace.health;
import org.apache.commons.lang.StringUtils; import org.dspace.content.Collection;
import org.dspace.content.DSpaceObject;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.CollectionService;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.eperson.EPerson; import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.eperson.factory.EPersonServiceFactory; import org.dspace.eperson.factory.EPersonServiceFactory;
import org.dspace.eperson.service.EPersonService; import org.dspace.eperson.service.EPersonService;
import org.dspace.eperson.service.GroupService;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID;
/** /**
* @author LINDAT/CLARIN dev team * @author LINDAT/CLARIN dev team
@@ -26,11 +30,12 @@ import java.util.UUID;
public class UserCheck extends Check { public class UserCheck extends Check {
private static final EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); private static final EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
private static final GroupService groupService = EPersonServiceFactory.getInstance().getGroupService();
private static final CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
@Override @Override
public String run( ReportInfo ri ) { public String run( ReportInfo ri ) {
Context context = new Context(); Context context = new Context();
Core core = new Core(context);
String ret = ""; String ret = "";
Map<String, Integer> info = new HashMap<String, Integer>(); Map<String, Integer> info = new HashMap<String, Integer>();
try { try {
@@ -81,20 +86,23 @@ public class UserCheck extends Check {
try { try {
// empty group // empty group
List<String> egs = core.getEmptyGroups(); List<Group> emptyGroups = groupService.getEmptyGroups(context);
ret += String.format( ret += String.format("Empty groups: #%d\n ", emptyGroups.size());
"Empty groups: #%d\n %s\n", for (Group group : emptyGroups) {
egs.size(), StringUtils.join(egs, ",\n ")); ret += String.format("id=%s;name=%s,\n ", group.getID(), group.getName() );
}
List<UUID> subs = core.getSubscribers(); //subscribers
List<EPerson> subscribers = ePersonService.findEPeopleWithSubscription(context);
ret += String.format( ret += String.format(
"Subscribers: #%d [%s]\n", "Subscribers: #%d [%s]\n",
subs.size(), StringUtils.join(subs, ", ")); subscribers.size(), formatIds(subscribers));
subs = core.getSubscribedCollections(); //subscribed collections
List<Collection> subscribedCols = collectionService.findCollectionsWithSubscribers(context);
ret += String.format( ret += String.format(
"Subscribed cols.: #%d [%s]\n", "Subscribed cols.: #%d [%s]\n",
subs.size(), StringUtils.join(subs, ", ")); subscribedCols.size(), formatIds(subscribedCols));
context.complete(); context.complete();
@@ -104,4 +112,13 @@ public class UserCheck extends Check {
return ret; return ret;
} }
private String formatIds(List<? extends DSpaceObject> objects){
StringBuilder ids = new StringBuilder();
for(DSpaceObject o : objects){
ids.append(o.getID())
.append(", ");
}
return ids.toString();
}
} }

View File

@@ -151,4 +151,9 @@ public class BasicWorkflowItemServiceImpl implements BasicWorkflowItemService {
public List<BasicWorkflowItem> findByOwner(Context context, EPerson ePerson) throws SQLException { public List<BasicWorkflowItem> findByOwner(Context context, EPerson ePerson) throws SQLException {
return workflowItemDAO.findByOwner(context, ePerson); return workflowItemDAO.findByOwner(context, ePerson);
} }
@Override
public int countTotal(Context context) throws SQLException {
return workflowItemDAO.countRows(context);
}
} }

View File

@@ -35,4 +35,6 @@ public interface BasicWorkflowItemDAO extends GenericDAO<BasicWorkflowItem> {
public List<BasicWorkflowItem> findByPooledTasks(Context context, EPerson ePerson) throws SQLException; public List<BasicWorkflowItem> findByPooledTasks(Context context, EPerson ePerson) throws SQLException;
public List<BasicWorkflowItem> findByOwner(Context context, EPerson ePerson) throws SQLException; public List<BasicWorkflowItem> findByOwner(Context context, EPerson ePerson) throws SQLException;
int countRows(Context context) throws SQLException;
} }

View File

@@ -74,4 +74,9 @@ public class BasicWorkflowItemDAOImpl extends AbstractHibernateDAO<BasicWorkflow
criteria.add(Restrictions.eq("owner", ePerson)); criteria.add(Restrictions.eq("owner", ePerson));
return list(criteria); return list(criteria);
} }
@Override
public int countRows(Context context) throws SQLException {
return count(createQuery(context, "SELECT count(*) FROM BasicWorkflowItem"));
}
} }

View File

@@ -27,4 +27,6 @@ public interface BasicWorkflowItemService extends WorkflowItemService<BasicWorkf
public List<BasicWorkflowItem> findPooledTasks(Context context, EPerson ePerson) throws SQLException; public List<BasicWorkflowItem> findPooledTasks(Context context, EPerson ePerson) throws SQLException;
public List<BasicWorkflowItem> findByOwner(Context context, EPerson ePerson) throws SQLException; public List<BasicWorkflowItem> findByOwner(Context context, EPerson ePerson) throws SQLException;
int countTotal(Context context) throws SQLException;
} }