Java tutorial
/* * Copyright 2015, Red Hat, Inc. and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.zanata.action; import static org.zanata.webhook.events.ProjectMaintainerChangedEvent.ChangeType; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.ListMultimap; import com.google.common.collect.Lists; import org.apache.commons.lang3.StringUtils; import javax.enterprise.inject.Model; import javax.faces.bean.ViewScoped; import javax.inject.Inject; import javax.inject.Named; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.hibernate.Session; import org.zanata.dao.PersonDAO; import org.zanata.dao.ProjectDAO; import org.zanata.exception.AuthorizationException; import org.zanata.i18n.Messages; import org.zanata.model.HLocale; import org.zanata.model.HPerson; import org.zanata.model.HProject; import org.zanata.model.HProjectLocaleMember; import org.zanata.model.HProjectMember; import org.zanata.model.LocaleRole; import org.zanata.model.PersonProjectMemberships; import org.zanata.model.ProjectRole; import org.zanata.model.WebHook; import org.zanata.security.ZanataIdentity; import org.zanata.service.LocaleService; import org.zanata.service.ProjectService; import org.zanata.service.impl.LocaleServiceImpl; import org.zanata.service.impl.ProjectServiceImpl; import org.zanata.service.impl.WebhookServiceImpl; import org.zanata.ui.AbstractAutocomplete; import org.zanata.ui.faces.FacesMessages; import org.zanata.util.ServiceLocator; import javax.faces.application.FacesMessage; import java.io.Serializable; import java.util.ArrayList; import java.util.List; /* * Backing bean for project permissions dialog. * * Template is person-permissions-modal.xhtml */ @Named("projectPermissionDialog") @ViewScoped @Model @Transactional public class ProjectPermissionDialog extends AbstractAutocomplete<HPerson> implements Serializable { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ProjectPermissionDialog.class); private static final long serialVersionUID = 2295330844926429686L; @Inject private FacesMessages facesMessages; @Inject private Messages msgs; @Inject private ZanataIdentity identity; @Inject private LocaleService localeServiceImpl; @Inject private WebhookServiceImpl webhookServiceImpl; @Inject private PersonDAO personDAO; @Inject private ProjectDAO projectDAO; @Inject private ProjectService projectServiceImpl; @Inject private Session session; private PersonProjectMemberships data; private HProject project; public void setData(HProject project, HPerson person) { this.project = project; setPerson(person); // reset autocomplete data this.reset(); } /** * Prepare the permission dialog to update permissions for the given person. * * @param person * to show in permission dialog */ private void setPerson(HPerson person) { final List<ProjectRole> projectRoles = new ArrayList<>(); for (HProjectMember membership : getProject().getMembers()) { if (membership.getPerson().equals(person)) { projectRoles.add(membership.getRole()); } } final ListMultimap<HLocale, LocaleRole> localeRoles = ArrayListMultimap.create(); for (HProjectLocaleMember membership : getProject().getLocaleMembers()) { if (membership.getPerson().equals(person)) { localeRoles.put(membership.getLocale(), membership.getRole()); } } data = new PersonProjectMemberships(person, projectRoles, localeRoles); LocaleService localeServiceImpl = ServiceLocator.instance().getInstance(LocaleServiceImpl.class); List<HLocale> locales = localeServiceImpl.getSupportedLanguageByProject(getProject().getSlug()); data.ensureLocalesPresent(locales); } /** * Ensure that the permission dialog has no person selected. */ public void clearPerson() { data = null; } /** * Check whether the selected person is the last maintainer of the project. */ public boolean lastMaintainerSelected() { if (data == null || data.getPerson() == null) { return false; } project = projectDAO.findById(getProject().getId()); return project.getMaintainers().size() <= 1 && project.getMaintainers().contains(data.getPerson()); } /** * Indicate whether any of the permissions are selected in the person * permission dialog. * * @return false if no permissions are selected in the dialog, otherwise * true */ public boolean anySelected() { return data != null && data.hasAnyPermissions(); } /** * Update role membership for a project-specific role based on the current * checkbox value. * * @param role * the role to assign or remove for the current person * @param checked * the current checkbox value */ public void bindProjectRole(String role, boolean checked) { if (StringUtils.equalsIgnoreCase(role, ProjectRole.TranslationMaintainer.name())) { data.setTranslationMaintainer(checked); } else if (StringUtils.equalsIgnoreCase(role, ProjectRole.Maintainer.name())) { data.setMaintainer(checked); } } /** * Update role membership for a locale-specific role based on the current * checkbox value. * * @param localeRole * represents both the locale and the role format: * {localeId}:{role}. e.g en-US:Reviewer * @param checked * the current checkbox value */ public void bindTranslationRole(String localeRole, boolean checked) { String[] localeRoleList = StringUtils.split(localeRole, ':'); final HLocale hLocale = localeServiceImpl.getByLocaleId(localeRoleList[0]); String role = localeRoleList[1]; final Optional<PersonProjectMemberships.LocaleRoles> matchingLocaleRoles = Iterables .tryFind(data.getLocaleRoles(), localeEqualsPredicate(hLocale)); if (matchingLocaleRoles.isPresent()) { PersonProjectMemberships.LocaleRoles localeRoles = matchingLocaleRoles.get(); if (StringUtils.equalsIgnoreCase(role, LocaleRole.Translator.name())) { localeRoles.setTranslator(checked); } else if (StringUtils.equalsIgnoreCase(role, LocaleRole.Reviewer.name())) { localeRoles.setReviewer(checked); } else if (StringUtils.equalsIgnoreCase(role, LocaleRole.Coordinator.name())) { localeRoles.setCoordinator(checked); } else if (StringUtils.equalsIgnoreCase(role, LocaleRole.Glossarist.name())) { localeRoles.setGlossarist(checked); } } else { // No LocaleRoles for the given locale, so create a new one. List<LocaleRole> roleList = Lists.newArrayList(LocaleRole.valueOf(role)); data.addLocaleRoles(hLocale, roleList); } } /** * Get a predicate that checks if a LocaleRoles.getLocale() is the given * locale. */ private Predicate<PersonProjectMemberships.LocaleRoles> localeEqualsPredicate(final HLocale hLocale) { return new Predicate<PersonProjectMemberships.LocaleRoles>() { @Override public boolean apply(PersonProjectMemberships.LocaleRoles input) { return input.getLocale().equals(hLocale); } }; } /** * Save the permissions selections from permissionDialogData to the * database. */ @Transactional public void saveSelections() { if (data == null) { log.error("Tried to save permissionDialogData but it is null"); return; } project = projectDAO.findById(getProject().getId()); // Hibernate will have problems working with detached HPerson and // HLocale // so they are all attached before any persistence is attempted. HPerson person = personDAO.findById(data.getPerson().getId()); session.refresh(person); data.setPerson(person); for (PersonProjectMemberships.LocaleRoles roles : data.getLocaleRoles()) { roles.setLocale(localeServiceImpl.getByLocaleId(roles.getLocale().getLocaleId())); } final boolean canManageMembers = identity.hasPermission(project, "manage-members"); final boolean canManageTransMembers = identity.hasPermission(project, "manage-translation-members"); final boolean canChangeAnyMembers = canManageMembers || canManageTransMembers; List<ProjectServiceImpl.UpdatedRole> updatedRoles = null; if (canManageMembers) { // generate a warning if trying to remove last maintainer // business rule in project will prevent actual removal if (!data.isMaintainer() && project.getMaintainers().size() <= 1 && project.getMaintainers().contains(data.getPerson())) { facesMessages.addGlobal(FacesMessage.SEVERITY_INFO, msgs.get("jsf.project.NeedAtLeastOneMaintainer")); } updatedRoles = projectServiceImpl.updateProjectPermissions(project, data); } if (canManageTransMembers) { projectServiceImpl.updateLocalePermissions(project, data); } if (canChangeAnyMembers) { projectDAO.makePersistent(project); if (!updatedRoles.isEmpty()) { List<WebHook> webHooks = project.getWebHooks(); for (ProjectServiceImpl.UpdatedRole updatedRole : updatedRoles) { ChangeType changeType = updatedRole.isAdded() ? ChangeType.ADD : ChangeType.REMOVE; webhookServiceImpl.processWebhookMaintainerChanged(project.getSlug(), updatedRole.getUsername(), updatedRole.getRole(), webHooks, changeType); } } } else { throw new AuthorizationException("You are not authorized to manage permissions for this project."); } } @Override public List<HPerson> suggest() { return getPersonDAO().findAllEnabledContainingName(getQuery()); } private PersonDAO getPersonDAO() { return ServiceLocator.instance().getInstance(PersonDAO.class); } @Override public void onSelectItemAction() { String selected = getSelectedItem(); HPerson selectedPerson = getPersonDAO().findByUsername(selected); if (selectedPerson != null) { setPerson(selectedPerson); } } public PersonProjectMemberships getData() { return this.data; } public HProject getProject() { return this.project; } }