Java tutorial
/** * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at license/ESCIDOC.LICENSE * or https://www.escidoc.org/license/ESCIDOC.LICENSE . * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at license/ESCIDOC.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * * Copyright 2012 Fachinformationszentrum Karlsruhe Gesellschaft * fuer wissenschaftlich-technische Information mbH and Max-Planck- * Gesellschaft zur Foerderung der Wissenschaft e.V. * All rights reserved. Use is subject to license terms. */ package org.escidoc.browser.ui.useraccount; import com.google.common.base.Preconditions; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.data.util.BeanItem; import com.vaadin.data.util.BeanItemContainer; import com.vaadin.terminal.ThemeResource; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Component; import com.vaadin.ui.ComponentContainer; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.NativeSelect; import com.vaadin.ui.Panel; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import com.vaadin.ui.Window.Notification; import org.escidoc.browser.controller.UserAccountController; import org.escidoc.browser.model.PropertyId; import org.escidoc.browser.model.ResourceModel; import org.escidoc.browser.model.ResourceType; import org.escidoc.browser.model.internal.UserProxy; import org.escidoc.browser.repository.Repositories; import org.escidoc.browser.repository.RoleRepository.RoleModel; import org.escidoc.browser.ui.Router; import org.escidoc.browser.ui.ViewConstants; import org.escidoc.browser.ui.role.OnRoleSelect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Set; import de.escidoc.core.client.exceptions.EscidocClientException; import de.escidoc.core.resources.aa.role.ScopeDef; import de.escidoc.core.resources.aa.useraccount.Grant; import de.escidoc.core.resources.common.reference.Reference; @SuppressWarnings("serial") public class UserRolesView extends Panel { private final static Logger LOG = LoggerFactory.getLogger(UserRolesView.class); private final class OnRemoveGrant implements Button.ClickListener { private Grant grant; private UserProxy userProxy; private Repositories repos; private Window mainWindow; public OnRemoveGrant(Grant grant, UserProxy userProxy, Repositories repos, Window mainWindow) { Preconditions.checkNotNull(grant, "grant is null: %s", grant); Preconditions.checkNotNull(userProxy, "userProxy is null: %s", userProxy); Preconditions.checkNotNull(repos, "repo is null: %s", repos); Preconditions.checkNotNull(mainWindow, "mainWindow is null: %s", mainWindow); this.grant = grant; this.repos = repos; this.userProxy = userProxy; this.mainWindow = mainWindow; } @Override public void buttonClick(final ClickEvent event) { try { revokeGrantInServer(); updateView(event); showSuccessMessage(); } catch (EscidocClientException e) { showErrorMessage(e); } } private void showErrorMessage(EscidocClientException e) { mainWindow.showNotification("Error Message", "Something wrong happens. Cause: " + e.getMessage(), Notification.TYPE_ERROR_MESSAGE); } private void showSuccessMessage() { mainWindow.showNotification("", "Sucessfully revoke " + grant.getXLinkTitle() + " from " + userProxy.getName(), Notification.TYPE_TRAY_NOTIFICATION); } private void revokeGrantInServer() throws EscidocClientException { repos.user().revokeGrant(userProxy.getId(), grant); } private void updateView(final ClickEvent event) { VerticalLayout component = (VerticalLayout) event.getButton().getParent().getParent(); component.removeComponent(event.getButton().getParent()); } } private final ComponentContainer rolesLayout = new VerticalLayout(); private final UserProxy userProxy; private final UserAccountController controller; private final Repositories repositories; private final Router router; // TODO CRUD View for User's Roles. // TODO View Layout: roleName | scopedOnResourceType | resourceName (resourceId) | removeBtn <-- row layout // TODO duplicate code for assigning grant and updating/showing grant // TODO Update: Edit existing role for the selected user. Change Role, Scope, Resource, etc // TODO PDP request??? public UserRolesView(UserProxy userProxy, UserAccountController controller, Repositories repositories, Router router) throws EscidocClientException { this.userProxy = userProxy; this.controller = controller; this.repositories = repositories; this.router = router; init(); } private void init() throws EscidocClientException { setCaption(ViewConstants.USER_ROLES); setCaption("Roles Panel"); ((VerticalLayout) rolesLayout).setMargin(true); setContent(rolesLayout); listRolesForUser(rolesLayout); } private void listRolesForUser(ComponentContainer grantListLayout) throws EscidocClientException { grantListLayout.removeAllComponents(); if (controller.getGrantsForUser(userProxy.getId()).size() == 0) { grantListLayout.addComponent(new Label("<h2>The user has no roles.</h2>", Label.CONTENT_XHTML)); } else { showExistingGrants(grantListLayout); } grantListLayout.addComponent(buildGrantRowAddView()); } private void showExistingGrants(ComponentContainer grantListLayout) throws EscidocClientException { int rowNumber = 0; for (Grant grant : controller.getGrantsForUser(userProxy.getId())) { HorizontalLayout existingGrantRowLayout = buildEditGrantRowView(rowNumber, grant); existingGrantRowLayout.setData(Integer.valueOf(rowNumber)); rowNumber++; bind(existingGrantRowLayout, grant); grantListLayout.addComponent(existingGrantRowLayout); } } private Component buildGrantRowAddView() throws EscidocClientException { HorizontalLayout addGrantRow = newRowGrantLayout(); final NativeSelect resourceTypeSelect = buildResourceTypeSelect(); final NativeSelect resourceSelect = buildResourceSelect(resourceTypeSelect); final NativeSelect roleNameSelect = buildRoleNameSelect(resourceTypeSelect, resourceSelect); addGrantRow.addComponent(roleNameSelect); addGrantRow.addComponent(resourceTypeSelect); addGrantRow.addComponent(resourceSelect); final Button saveButton = buildAssignGrantButton(resourceSelect, roleNameSelect); addGrantRow.addComponent(saveButton); bindRoleName(roleNameSelect); return addGrantRow; } private HorizontalLayout buildEditGrantRowView(int rowNumber, Grant grant) { HorizontalLayout editGrantRow = newRowGrantLayout(); NativeSelect resourceTypeSelect = buildResourceTypeSelect(); NativeSelect resourceSelect = buildResourceSelect(resourceTypeSelect); NativeSelect roleNameSelect = buildRoleNameSelect(resourceTypeSelect, resourceSelect); editGrantRow.addComponent(roleNameSelect); editGrantRow.addComponent(resourceTypeSelect); editGrantRow.addComponent(resourceSelect); Button removeButton = buildRemoveButton(rowNumber, grant); editGrantRow.addComponent(removeButton); return editGrantRow; } private NativeSelect buildResourceSelect(NativeSelect resouceTypeSelect) { final NativeSelect resourceSelect = buildResourceSelect(); resouceTypeSelect.addListener(new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { if (event.getProperty().getValue() instanceof ResourceType) { try { bind(resourceSelect, loadData((ResourceType) event.getProperty().getValue())); } catch (UnsupportedOperationException e) { router.getMainWindow().showNotification(ViewConstants.ERROR, e.getMessage(), Window.Notification.TYPE_ERROR_MESSAGE); } catch (EscidocClientException e) { router.getMainWindow().showNotification(ViewConstants.ERROR, e.getMessage(), Window.Notification.TYPE_ERROR_MESSAGE); } } } private void bind(NativeSelect resourceSelect, BeanItemContainer<ResourceModel> dataSource) { resourceSelect.setContainerDataSource(dataSource); resourceSelect.setItemCaptionPropertyId(PropertyId.NAME); } private BeanItemContainer<ResourceModel> loadData(ResourceType selectedType) throws EscidocClientException { final BeanItemContainer<ResourceModel> dataSource = newContainer(); for (final ResourceModel rm : findAll(selectedType)) { dataSource.addItem(rm); } return dataSource; } private List<ResourceModel> findAll(ResourceType type) throws EscidocClientException { List<ResourceModel> list = repositories.findByType(type).findAll(); Collections.sort(list, new Comparator<ResourceModel>() { @Override public int compare(ResourceModel o1, ResourceModel o2) { return o1.getName().compareToIgnoreCase(o2.getName()); } }); return list; } }); return resourceSelect; } private static NativeSelect buildResourceTypeSelect() { final NativeSelect resourceTypeSelect = buildResourceSelect(); resourceTypeSelect.setWidth("100px"); return resourceTypeSelect; } private Button buildAssignGrantButton(final NativeSelect resourceSelect, final NativeSelect roleNameSelect) { Button assignGrantButton = new Button(); assignGrantButton.setIcon(new ThemeResource("images/assets/plus.png")); assignGrantButton.addListener(new Button.ClickListener() { @Override public void buttonClick(@SuppressWarnings("unused") ClickEvent event) { try { if (getSelectedRole() == null) { router.getMainWindow().showNotification("Role can not be empty", "", Window.Notification.TYPE_WARNING_MESSAGE); return; } Grant grant = assignGrantInServer(); updateView(); showSuccessMessage(grant); } catch (EscidocClientException e) { router.getMainWindow().showNotification("Error Message", "Something wrong happens. Cause: " + e.getMessage(), Notification.TYPE_ERROR_MESSAGE); } } private void showSuccessMessage(Grant grant) { router.getMainWindow().showNotification("", "Sucessfully assign grant " + grant.getXLinkTitle() + " to " + userProxy.getName(), Notification.TYPE_TRAY_NOTIFICATION); } private Grant assignGrantInServer() throws EscidocClientException { return repositories.user().assign(userProxy.getId()).withRole(getSelectedRole()) .onResources(getSelectedResources()).execute(); } private RoleModel getSelectedRole() { final Object value = roleNameSelect.getValue(); if (value instanceof RoleModel) { return (RoleModel) value; } return null; } private Set<ResourceModel> getSelectedResources() { final Object value = resourceSelect.getValue(); if (value instanceof ResourceModel) { return Collections.singleton((ResourceModel) value); } return Collections.emptySet(); } private void updateView() throws EscidocClientException { listRolesForUser(rolesLayout); } }); return assignGrantButton; } private void bindRoleName(NativeSelect roleNameSelect) throws EscidocClientException { roleNameSelect.setContainerDataSource(buildRoleNameDataSource()); roleNameSelect.setItemCaptionPropertyId(PropertyId.NAME); } private static HorizontalLayout newRowGrantLayout() { HorizontalLayout grantLayout = new HorizontalLayout(); grantLayout.setSpacing(true); grantLayout.setMargin(true, false, false, false); return grantLayout; } private static NativeSelect buildResourceSelect() { NativeSelect select = new NativeSelect(); select.setWidth("250px"); select.setNullSelectionAllowed(false); select.setMultiSelect(false); select.setNewItemsAllowed(false); select.setImmediate(true); return select; } private NativeSelect buildRoleNameSelect(final NativeSelect resourceTypeSelect, final NativeSelect resourceSelect) { NativeSelect roleNameSelect = new NativeSelect(); roleNameSelect.setMultiSelect(false); roleNameSelect.setNewItemsAllowed(false); roleNameSelect.setNullSelectionAllowed(false); roleNameSelect.setImmediate(true); roleNameSelect.setRequired(true); roleNameSelect.setRequiredError("Role can not be empty."); roleNameSelect.addListener(new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { if (event.getProperty().getValue() instanceof RoleModel) { final List<ResourceType> resourceTypeList = new ArrayList<ResourceType>(); for (final ResourceType resourceType : buildScopeDefinitions( (RoleModel) event.getProperty().getValue())) { if (resourceType != null && !resourceType.equals(ResourceType.COMPONENT)) { resourceTypeList.add(resourceType); } } resourceTypeSelect.removeAllItems(); bind(resourceTypeSelect, resourceTypeList); } } private void bind(NativeSelect resourceTypeSelect, List<ResourceType> resourceTypeList) { enableScoping(resourceTypeSelect, resourceTypeList.size() > 0); final BeanItemContainer<ResourceType> dataSource = new BeanItemContainer<ResourceType>( ResourceType.class, resourceTypeList); resourceTypeSelect.setContainerDataSource(dataSource); resourceTypeSelect.setItemCaptionPropertyId(PropertyId.NAME); if (dataSource.size() > 0) { resourceTypeSelect.setValue(dataSource.getIdByIndex(0)); } } private void enableScoping(NativeSelect resourceTypeSelect, boolean isEnabled) { resourceTypeSelect.setVisible(isEnabled); resourceSelect.setVisible(isEnabled); } }); return roleNameSelect; } private void bind(HorizontalLayout grantRow, Grant grant) throws EscidocClientException { NativeSelect roleNameSelect = (NativeSelect) grantRow.getComponent(0); roleNameSelect.setContainerDataSource(buildRoleNameDataSource()); roleNameSelect.setItemCaptionPropertyId(PropertyId.NAME); // // FIXME this causes a bad performance Collection<?> collection = roleNameSelect.getContainerDataSource().getItemIds(); for (Object object : collection) { ResourceModel rm = (ResourceModel) object; if (grant.getProperties() == null || grant.getProperties().getRole() == null || grant.getProperties().getRole().getXLinkTitle() == null) { return; } if (rm.getName().equalsIgnoreCase(grant.getProperties().getRole().getXLinkTitle())) { roleNameSelect.setValue(rm); } } bindResourceType(grantRow, (RoleModel) roleNameSelect.getValue(), grant); } private void bindResourceType(HorizontalLayout grantRow, RoleModel value, Grant grant) throws EscidocClientException { final List<ResourceType> resourceTypeList = buildScopeDefinitions(value); NativeSelect resourceTypeSelect = (NativeSelect) grantRow.getComponent(1); final BeanItemContainer<ResourceType> dataSource = new BeanItemContainer<ResourceType>(ResourceType.class, resourceTypeList); resourceTypeSelect.setContainerDataSource(dataSource); resourceTypeSelect.setItemCaptionPropertyId(PropertyId.NAME); // TODO refactor this if (dataSource.size() > 0 && (NativeSelect) grantRow.getComponent(2) != null) { resourceTypeSelect.setValue(dataSource.getIdByIndex(0)); loadData((NativeSelect) grantRow.getComponent(2), dataSource.getIdByIndex(0)); for (Object object : ((NativeSelect) grantRow.getComponent(2)).getContainerDataSource().getItemIds()) { Reference assignedOn = grant.getProperties().getAssignedOn(); if (assignedOn != null && getRoleName(object).equalsIgnoreCase(assignedOn.getXLinkTitle())) { ((NativeSelect) grantRow.getComponent(2)).select(object); } } } } private static String getRoleName(Object object) { return ((ResourceModel) object).getName(); } private static List<ResourceType> buildScopeDefinitions(RoleModel value) { final List<ResourceType> resourceTypeList = new ArrayList<ResourceType>(); for (ScopeDef scopeDef : OnRoleSelect.getScopeDefinitions(value)) { final ResourceType resourceType = ResourceType.convert(scopeDef.getRelationAttributeObjectType()); if (resourceType != null && !resourceType.equals(ResourceType.COMPONENT)) { resourceTypeList.add(resourceType); } } return resourceTypeList; } private void loadData(NativeSelect assignedOn, ResourceType type) throws UnsupportedOperationException, EscidocClientException { final BeanItemContainer<ResourceModel> dataSource = newContainer(); for (final ResourceModel rm : findAll(type)) { dataSource.addItem(rm); } configureList(assignedOn, dataSource); } private static void configureList(NativeSelect assignedOn, final BeanItemContainer<ResourceModel> container) { assignedOn.setContainerDataSource(container); assignedOn.setItemCaptionPropertyId(PropertyId.NAME); } private static BeanItemContainer<ResourceModel> newContainer() { return new BeanItemContainer<ResourceModel>(ResourceModel.class); } private List<ResourceModel> findAll(ResourceType type) throws EscidocClientException { List<ResourceModel> list = repositories.findByType(type).findAll(); Collections.sort(list, new Comparator<ResourceModel>() { @Override public int compare(ResourceModel o1, ResourceModel o2) { ResourceModel p1 = o1; ResourceModel p2 = o2; return p1.getName().compareToIgnoreCase(p2.getName()); } }); return list; } private BeanItemContainer<ResourceModel> roleNameDataSource; private BeanItemContainer<ResourceModel> buildRoleNameDataSource() throws EscidocClientException { if (roleNameDataSource == null) { roleNameDataSource = new BeanItemContainer<ResourceModel>(ResourceModel.class); for (ResourceModel resourceModel : repositories.role().findAll()) { if (RoleModel.isValid(resourceModel)) { BeanItem<ResourceModel> item = roleNameDataSource.addItem(resourceModel); Preconditions.checkNotNull(item, "item is null: %s", item); } roleNameDataSource.addItem(resourceModel.getName()); } } return roleNameDataSource; } private static NativeSelect buildRoleNameSelect() { NativeSelect roleNameSelect = new NativeSelect(); roleNameSelect.setMultiSelect(false); roleNameSelect.setNewItemsAllowed(false); roleNameSelect.setNullSelectionAllowed(false); roleNameSelect.setImmediate(true); return roleNameSelect; } private Button buildRemoveButton(int rowNumber, Grant grant) { Button removeButton = new Button(); removeButton.setIcon(new ThemeResource("images/assets/minus.png")); removeButton.setData(Integer.valueOf(rowNumber)); removeButton.addListener(new OnRemoveGrant(grant, userProxy, repositories, router.getMainWindow())); return removeButton; } }