package com.thinkbiganalytics.feedmgr.service.category;
/*-
* #%L
* thinkbig-feed-manager-controller
* %%
* Copyright (C) 2017 ThinkBig Analytics
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import com.thinkbiganalytics.feedmgr.InvalidOperationException;
import com.thinkbiganalytics.feedmgr.rest.model.FeedCategory;
import com.thinkbiganalytics.feedmgr.rest.model.UserField;
import com.thinkbiganalytics.feedmgr.rest.model.UserProperty;
import com.thinkbiganalytics.feedmgr.security.FeedServicesAccessControl;
import com.thinkbiganalytics.feedmgr.service.UserPropertyTransform;
import com.thinkbiganalytics.feedmgr.service.security.SecurityService;
import com.thinkbiganalytics.metadata.api.MetadataAccess;
import com.thinkbiganalytics.metadata.api.MetadataCommand;
import com.thinkbiganalytics.metadata.api.category.Category;
import com.thinkbiganalytics.metadata.api.category.CategoryProvider;
import com.thinkbiganalytics.metadata.api.category.security.CategoryAccessControl;
import com.thinkbiganalytics.metadata.api.extension.UserFieldDescriptor;
import com.thinkbiganalytics.security.AccessController;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.inject.Inject;
/**
* An implementation of {@link FeedManagerCategoryService} backed by a {@link CategoryProvider}.
*/
public class DefaultFeedManagerCategoryService implements FeedManagerCategoryService {
@Inject
CategoryProvider categoryProvider;
@Inject
CategoryModelTransform categoryModelTransform;
@Inject
MetadataAccess metadataAccess;
@Inject
private SecurityService securityService;
@Inject
private AccessController accessController;
@Override
public Collection<FeedCategory> getCategories() {
return metadataAccess.read((MetadataCommand<Collection<FeedCategory>>) () -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_CATEGORIES);
List<Category> domainCategories = categoryProvider.findAll();
return categoryModelTransform.domainToFeedCategory(domainCategories);
});
}
@Override
public FeedCategory getCategoryById(final String id) {
return metadataAccess.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_CATEGORIES);
final Category.ID domainId = categoryProvider.resolveId(id);
final Category domainCategory = categoryProvider.findById(domainId);
return categoryModelTransform.domainToFeedCategory(domainCategory);
});
}
@Override
public FeedCategory getCategoryBySystemName(final String name) {
return metadataAccess.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_CATEGORIES);
final Category domainCategory = categoryProvider.findBySystemName(name);
return categoryModelTransform.domainToFeedCategory(domainCategory);
});
}
@Override
public void saveCategory(final FeedCategory category) {
final Category.ID domainId = metadataAccess.commit(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.EDIT_CATEGORIES);
// Determine the system name
if (category.getId() == null) {
category.generateSystemName();
} else {
final FeedCategory oldCategory = getCategoryById(category.getId());
if (oldCategory != null && !oldCategory.getName().equalsIgnoreCase(category.getName())) {
//names have changed
//only regenerate the system name if there are no related feeds
if (oldCategory.getRelatedFeeds() == 0) {
category.generateSystemName();
}
}
}
// Update the domain entity
final Category domainCategory = categoryProvider.update(categoryModelTransform.feedCategoryToDomain(category));
// Repopulate identifier
category.setId(domainCategory.getId().toString());
///update access control
//TODO only do this when modifying the access control
if (domainCategory.getAllowedActions().hasPermission(CategoryAccessControl.CHANGE_PERMS)) {
category.toRoleMembershipChangeList().stream().forEach(roleMembershipChange -> securityService.changeCategoryRoleMemberships(category.getId(), roleMembershipChange));
}
return domainCategory.getId();
});
// Update user-defined fields (must be outside metadataAccess)
final Set<UserFieldDescriptor> userFields = (category.getUserFields() != null) ? UserPropertyTransform.toUserFieldDescriptors(category.getUserFields()) : Collections.emptySet();
categoryProvider.setFeedUserFields(domainId, userFields);
}
@Override
public boolean deleteCategory(final String categoryId) throws InvalidOperationException {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.EDIT_CATEGORIES);
final Category.ID domainId = metadataAccess.read(() -> categoryProvider.resolveId(categoryId));
categoryProvider.deleteById(domainId);
return true;
}
@Nonnull
@Override
public Set<UserField> getUserFields() {
return metadataAccess.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_CATEGORIES);
return UserPropertyTransform.toUserFields(categoryProvider.getUserFields());
});
}
@Override
public void setUserFields(@Nonnull Set<UserField> userFields) {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ADMIN_CATEGORIES);
categoryProvider.setUserFields(UserPropertyTransform.toUserFieldDescriptors(userFields));
}
@Nonnull
@Override
public Set<UserProperty> getUserProperties() {
return metadataAccess.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_CATEGORIES);
return UserPropertyTransform.toUserProperties(Collections.emptyMap(), categoryProvider.getUserFields());
});
}
}