From 5e493556ca8004f43795185714651b2eec3a20af Mon Sep 17 00:00:00 2001 From: jensp Date: Fri, 3 Mar 2017 14:02:02 +0000 Subject: [PATCH] CCM NG/ccm-core: Code cleanup git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4617 8810af33-2d31-482b-a856-94f89814c4df Former-commit-id: a71eeed9c32c07b9750db213105d772695482d49 --- .../categorization/Categorization.java | 2 + .../org/libreccm/categorization/Category.java | 22 +++ .../categorization/CategoryManager.java | 151 +++++++++++++++--- .../core/AbstractEntityRepository.java | 5 +- .../org/libreccm/formbuilder/WidgetLabel.java | 2 +- 5 files changed, 154 insertions(+), 28 deletions(-) diff --git a/ccm-core/src/main/java/org/libreccm/categorization/Categorization.java b/ccm-core/src/main/java/org/libreccm/categorization/Categorization.java index fd3d7bcb4..a86d0a234 100644 --- a/ccm-core/src/main/java/org/libreccm/categorization/Categorization.java +++ b/ccm-core/src/main/java/org/libreccm/categorization/Categorization.java @@ -40,6 +40,8 @@ import static org.libreccm.core.CoreConstants.DB_SCHEMA; import org.libreccm.security.Relation; +import javax.persistence.FetchType; + /** * Association class describing the association between a category and an * object. Instances of these class should not created manually. The methods diff --git a/ccm-core/src/main/java/org/libreccm/categorization/Category.java b/ccm-core/src/main/java/org/libreccm/categorization/Category.java index 08c35060f..f9f7f8c4a 100644 --- a/ccm-core/src/main/java/org/libreccm/categorization/Category.java +++ b/ccm-core/src/main/java/org/libreccm/categorization/Category.java @@ -79,12 +79,34 @@ import javax.xml.bind.annotation.XmlRootElement; name = "Category.findByName", query = "SELECT c FROM Category c WHERE c.name = :name") , + @NamedQuery( + name = "Category.countAssignedCategories", + query = "SELECT COUNT(c) FROM Categorization c " + + "WHERE c.categorizedObject = :object" + ) + , + @NamedQuery( + name = "Category.isCategorized", + query = "SELECT (CASE WHEN COUNT(c) > 0 THEN true ELSE false END) " + + "FROM Categorization c " + + "WHERE c.categorizedObject = :object") + , + @NamedQuery( + name = "Category.countObjects", + query = "SELECT COUNT(c) FROM Categorization c " + + "WHERE c.category = :category") + , @NamedQuery( name = "Category.hasObjects", query = "SELECT (CASE WHEN COUNT(c) > 0 THEN true ELSE false END) " + "FROM Categorization c " + "WHERE c.category = :category") , + @NamedQuery( + name = "Category.countSubCategories", + query = "SELECT COUNT(c) FROM Category c " + + "WHERE c.parentCategory =:category") + , @NamedQuery( name = "Category.hasSubCategories", query = "SELECT (CASE WHEN COUNT(c) > 0 THEN true ELSE false END) " diff --git a/ccm-core/src/main/java/org/libreccm/categorization/CategoryManager.java b/ccm-core/src/main/java/org/libreccm/categorization/CategoryManager.java index 6028f976d..61f67b7d4 100644 --- a/ccm-core/src/main/java/org/libreccm/categorization/CategoryManager.java +++ b/ccm-core/src/main/java/org/libreccm/categorization/CategoryManager.java @@ -55,15 +55,12 @@ public class CategoryManager { private static final Logger LOGGER = LogManager.getLogger( CategoryManager.class); - /** - * A {@link CategoryRepository} instance used to interact with the database. - */ - @Inject - private CategoryRepository categoryRepo; - @Inject private CcmObjectRepository ccmObjectRepo; + @Inject + private CategoryRepository categoryRepo; + @Inject private EntityManager entityManager; @@ -126,26 +123,36 @@ public class CategoryManager { final Category category, final String type) { - if (object == null) { - throw new IllegalArgumentException( - "Null can't be added to a category."); - } + Objects.requireNonNull(object, "Null can't be added to a category."); + Objects.requireNonNull(category, + "Can't add an object to category 'null'."); - if (category == null) { - throw new IllegalArgumentException( - "Can't add an object to category 'null'."); - } + final CcmObject addedObject = ccmObjectRepo + .findObjectById(object.getObjectId()) + .orElseThrow(() -> new IllegalArgumentException(String.format( + "No CcmObject with ID %d in the database. " + + "Where did that ID come from?", + object.getObjectId()))); + final Category assignedCategory = categoryRepo + .findById(category.getObjectId()) + .orElseThrow(() -> new IllegalArgumentException(String.format( + "No Category with ID %d in the database. " + + "Where did that ID come from?", + category.getObjectId()))); final Categorization categorization = new Categorization(); - categorization.setCategorizedObject(object); - categorization.setCategory(category); - categorization.setCategoryOrder(object.getCategories().size() + 1); - categorization.setObjectOrder(category.getObjects().size() + 1); + categorization.setCategorizedObject(addedObject); + categorization.setCategory(assignedCategory); + + final long categoryCount = countAssignedCategories(addedObject); + categorization.setCategoryOrder(categoryCount + 1); + final long objectCount = countObjects(assignedCategory); + categorization.setObjectOrder(objectCount + 1); categorization.setType(type); categorization.setIndex(false); - object.addCategory(categorization); - category.addObject(categorization); + addedObject.addCategory(categorization); + assignedCategory.addObject(categorization); // Saving a category requires the manage_category privilege which // may has not been granted to a user which is allowed to assign objects @@ -153,11 +160,75 @@ public class CategoryManager { // by executing CategoryRepository#save(Category) as the system user. shiro.getSystemUser().execute(() -> { entityManager.persist(categorization); - categoryRepo.save(category); - ccmObjectRepo.save(object); +// categoryRepo.save(assignedCategory); +// ccmObjectRepo.save(addedObject); }); } + /** + * Count the categories assigned to a {@link CcmObject}. + * + * @param object The object which categorisations are counted. + * + * @return The number of categorisations of the provided {@code object}. + */ + public long countAssignedCategories(final CcmObject object) { + + Objects.requireNonNull(object); + + final TypedQuery query = entityManager.createNamedQuery( + "Category.countAssignedCategories", Long.class); + query.setParameter("object", object); + + return query.getSingleResult(); + } + + /** + * Tests if an {@link CcmObject} is assigned to at least one category. + * + * @param object The object which is check for categorisations. + * + * @return {@code true} if the {@code object} is assigned to at least one + * category, {@code false} otherwise. + */ + public boolean isCategorized(final Object object) { + Objects.requireNonNull(object); + + final TypedQuery query = entityManager.createNamedQuery( + "Category.isCategorized", Boolean.class); + query.setParameter("object", object); + + return query.getSingleResult(); + } + + /** + * Counts the subcategories of a category. + * + * @param category The category for which the number of subcategories is + * determined. + * + * @return The number of subcategories of {@code category}. + */ + public long countSubCategories(final Category category) { + + Objects.requireNonNull(category, + "Can't count sub categories for category null."); + + final TypedQuery query = entityManager.createNamedQuery( + "Category.countSubCategories", Long.class); + query.setParameter("category", category); + + return query.getSingleResult(); + } + + /** + * Checks if a category has at least one subcategory. + * + * @param category The category to check for subcategories. + * + * @return {@code true} if {@code category} has at least on subcategory, + * {@code false} otherwise. + */ public boolean hasSubCategories(final Category category) { Objects.requireNonNull( @@ -171,6 +242,34 @@ public class CategoryManager { return query.getSingleResult(); } + /** + * Counts to how many {@link CcmObject}s a category has been assigned. + * + * @param category The category which objects are counted. + * + * @return The number of {@link CcmObject}s to which the {@code category} + * has been assigned. + */ + public long countObjects(final Category category) { + + Objects.requireNonNull(category, + "Can't count object in category null"); + + final TypedQuery query = entityManager.createNamedQuery( + "Category.countObjects", Long.class); + query.setParameter("category", category); + + return query.getSingleResult(); + } + + /** + * Checks if a category is assigned to at least one {@link CcmObject}. + * + * @param category The category to check for assigned objects. + * + * @return {@code true} if at least on {@link CcmObject} is assigned to the + * {@code category}, {@code false} otherwise. + */ public boolean hasObjects(final Category category) { Objects.requireNonNull(category, @@ -530,7 +629,7 @@ public class CategoryManager { + "the name '%s'.", sub.get().getName())); } - + if (sub.get().getParentCategory() != null) { final Category oldParent = sub.get().getParentCategory(); removeSubCategoryFromCategory(sub.get(), oldParent); @@ -780,13 +879,13 @@ public class CategoryManager { */ @Transactional(Transactional.TxType.REQUIRED) public String getCategoryPath(final Category category) { - + Objects.requireNonNull(category, "Can't get the path for category null"); - + final List tokens = new ArrayList<>(); Category current = categoryRepo.findById(category.getObjectId()) - .orElseThrow(() -> new IllegalArgumentException(String.format( + .orElseThrow(() -> new IllegalArgumentException(String.format( "No category with ID %d in the database. Where did that ID come from?", category.getObjectId()))); while (current.getParentCategory() != null) { diff --git a/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java b/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java index 920c61839..56ebc103c 100644 --- a/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java +++ b/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java @@ -241,6 +241,9 @@ public abstract class AbstractEntityRepository { */ @Transactional(Transactional.TxType.REQUIRED) public void save(final E entity) { + + Objects.requireNonNull(entity, "Can't save null."); + if (isNew(entity)) { initNewEntity(entity); entityManager.persist(entity); @@ -254,7 +257,7 @@ public abstract class AbstractEntityRepository { * example is assigning a (random) UUID to new entity which implements the * {@link Identifiable} interface. * - * @param entity The entity to init. + * @param entity The entity to initialise. */ protected void initNewEntity(final E entity) { //Empty default implementation diff --git a/ccm-core/src/main/java/org/libreccm/formbuilder/WidgetLabel.java b/ccm-core/src/main/java/org/libreccm/formbuilder/WidgetLabel.java index 327d451a5..9098cad0a 100644 --- a/ccm-core/src/main/java/org/libreccm/formbuilder/WidgetLabel.java +++ b/ccm-core/src/main/java/org/libreccm/formbuilder/WidgetLabel.java @@ -38,7 +38,7 @@ public class WidgetLabel extends Component implements Serializable { private static final long serialVersionUID = -2939505715812565159L; - @OneToOne + @OneToOne(mappedBy = "label") private Widget widget; public Widget getWidget() {