Package com.gitblit.wicket.panels

Source Code of com.gitblit.wicket.panels.RegistrantPermissionsPanel

/*
* Copyright 2012 gitblit.com.
*
* 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.
*/
package com.gitblit.wicket.panels;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.OddEvenItem;
import org.apache.wicket.markup.repeater.RefreshingView;
import org.apache.wicket.markup.repeater.util.ModelIteratorAdapter;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.eclipse.jgit.lib.PersonIdent;

import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.PermissionType;
import com.gitblit.Constants.RegistrantType;
import com.gitblit.models.RegistrantAccessPermission;
import com.gitblit.models.UserModel;
import com.gitblit.utils.DeepCopier;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.WicketUtils;

/**
* Allows user to manipulate registrant access permissions.
*
* @author James Moger
*
*/
public class RegistrantPermissionsPanel extends BasePanel {

  private static final long serialVersionUID = 1L;

  public enum Show {
    specified, mutable, effective;

    public boolean show(RegistrantAccessPermission ap) {
      switch (this) {
      case specified:
        return ap.mutable || ap.isOwner();
      case mutable:
        return ap.mutable;
      case effective:
        return true;
      default:
        return true;
      }
    }
  }

  private Show activeState = Show.mutable;

  public RegistrantPermissionsPanel(String wicketId, RegistrantType registrantType, List<String> allRegistrants, final List<RegistrantAccessPermission> permissions, final Map<AccessPermission, String> translations) {
    super(wicketId);
    setOutputMarkupId(true);

    /*
     * Permission view toggle buttons
     */
    Form<Void> permissionToggleForm = new Form<Void>("permissionToggleForm");
    permissionToggleForm.add(new ShowStateButton("showSpecified", Show.specified));
    permissionToggleForm.add(new ShowStateButton("showMutable", Show.mutable));
    permissionToggleForm.add(new ShowStateButton("showEffective", Show.effective));
    add(permissionToggleForm);

    /*
     * Permission repeating display
     */
    RefreshingView<RegistrantAccessPermission> dataView = new RefreshingView<RegistrantAccessPermission>("permissionRow") {
      private static final long serialVersionUID = 1L;

      @Override
            protected Iterator<IModel<RegistrantAccessPermission>> getItemModels() {
                // the iterator returns RepositoryPermission objects, but we need it to
                // return models
                return new ModelIteratorAdapter<RegistrantAccessPermission>(permissions.iterator()) {
                    @Override
                    protected IModel<RegistrantAccessPermission> model(RegistrantAccessPermission permission) {
                        return new CompoundPropertyModel<RegistrantAccessPermission>(permission);
                    }
                };
            }

            @Override
            protected Item<RegistrantAccessPermission> newItem(String id, int index, IModel<RegistrantAccessPermission> model) {
                // this item sets markup class attribute to either 'odd' or
                // 'even' for decoration
                return new OddEvenItem<RegistrantAccessPermission>(id, index, model);
            }

      @Override
      public void populateItem(final Item<RegistrantAccessPermission> item) {
        final RegistrantAccessPermission entry = item.getModelObject();
        if (RegistrantType.REPOSITORY.equals(entry.registrantType)) {
          String repoName = StringUtils.stripDotGit(entry.registrant);
          if (!entry.isMissing() && StringUtils.findInvalidCharacter(repoName) == null) {
            // repository, strip .git and show swatch
            Fragment repositoryFragment = new Fragment("registrant", "repositoryRegistrant", RegistrantPermissionsPanel.this);
            Component swatch = new Label("repositorySwatch", "&nbsp;").setEscapeModelStrings(false);
            WicketUtils.setCssBackground(swatch, entry.toString());
            repositoryFragment.add(swatch);
            Label registrant = new Label("repositoryName", repoName);
            repositoryFragment.add(registrant);
            item.add(repositoryFragment);
          } else {
            // regex or missing
            Label label = new Label("registrant", entry.registrant);
            WicketUtils.setCssStyle(label, "font-weight: bold;");
            item.add(label);
          }
        } else if (RegistrantType.USER.equals(entry.registrantType)) {
          // user
          PersonIdent ident = new PersonIdent(entry.registrant, "");
          UserModel user = app().users().getUserModel(entry.registrant);
          if (user != null) {
            ident = new PersonIdent(user.getDisplayName(), user.emailAddress == null ? user.getDisplayName() : user.emailAddress);
          }

          Fragment userFragment = new Fragment("registrant", "userRegistrant", RegistrantPermissionsPanel.this);
          userFragment.add(new GravatarImage("userAvatar", ident, 20));
          userFragment.add(new Label("userName", entry.registrant));
          item.add(userFragment);
        } else {
          // team
          Fragment teamFragment = new Fragment("registrant", "teamRegistrant", RegistrantPermissionsPanel.this);
          teamFragment.add(new Label("teamName", entry.registrant));
          item.add(teamFragment);
        }
        switch (entry.permissionType) {
        case ADMINISTRATOR:
          Label administrator = new Label("pType", entry.source == null ? getString("gb.administrator") : entry.source);
          WicketUtils.setHtmlTooltip(administrator, getString("gb.administratorPermission"));
          WicketUtils.setCssClass(administrator, "label label-inverse");
          item.add(administrator);
          break;
        case OWNER:
          Label owner = new Label("pType", getString("gb.owner"));
          WicketUtils.setHtmlTooltip(owner, getString("gb.ownerPermission"));
          WicketUtils.setCssClass(owner, "label label-info");
          item.add(owner);
          break;
        case TEAM:
          Label team = new Label("pType", entry.source == null ? getString("gb.team") : entry.source);
          WicketUtils.setHtmlTooltip(team, MessageFormat.format(getString("gb.teamPermission"), entry.source));
          WicketUtils.setCssClass(team, "label label-success");
          item.add(team);
          break;
        case REGEX:
          Label regex = new Label("pType", "regex");
          if (!StringUtils.isEmpty(entry.source)) {
            WicketUtils.setHtmlTooltip(regex, MessageFormat.format(getString("gb.regexPermission"), entry.source));
          }
          WicketUtils.setCssClass(regex, "label");
          item.add(regex);
          break;
        default:
          if (entry.isMissing()) {
            // repository is missing, this permission will be removed on save
            Label missing = new Label("pType", getString("gb.missing"));
            WicketUtils.setCssClass(missing, "label label-important");
            WicketUtils.setHtmlTooltip(missing, getString("gb.missingPermission"));
            item.add(missing);
          } else {
            // standard permission
            item.add(new Label("pType", "").setVisible(false));
          }
          break;
        }

        item.setVisible(activeState.show(entry));

        // use ajax to get immediate update of permission level change
        // otherwise we can lose it if they change levels and then add
        // a new repository permission
        final DropDownChoice<AccessPermission> permissionChoice = new DropDownChoice<AccessPermission>(
            "permission", Arrays.asList(AccessPermission.values()), new AccessPermissionRenderer(translations));
        // only allow changing an explicitly defined permission
        // this is designed to prevent changing a regex permission in
        // a repository
        permissionChoice.setEnabled(entry.mutable);
        permissionChoice.setOutputMarkupId(true);
        if (entry.mutable) {
          permissionChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") {

            private static final long serialVersionUID = 1L;

            @Override
            protected void onUpdate(AjaxRequestTarget target) {
              target.addComponent(permissionChoice);
            }
          });
        }

        item.add(permissionChoice);
      }
    };
    add(dataView);
    setOutputMarkupId(true);

    // filter out registrants we already have permissions for
    final List<String> registrants = new ArrayList<String>(allRegistrants);
    for (RegistrantAccessPermission rp : permissions) {
      if (rp.mutable) {
        // remove editable duplicates
        // this allows for specifying an explicit permission
        registrants.remove(rp.registrant);
      } else if (rp.isAdmin()) {
        // administrators can not have their permission changed
        registrants.remove(rp.registrant);
      } else if (rp.isOwner()) {
        // owners can not have their permission changed
        registrants.remove(rp.registrant);
      }
    }

    /*
     * Add permission form
     */
    IModel<RegistrantAccessPermission> addPermissionModel = new CompoundPropertyModel<RegistrantAccessPermission>(new RegistrantAccessPermission(registrantType));
    Form<RegistrantAccessPermission> addPermissionForm = new Form<RegistrantAccessPermission>("addPermissionForm", addPermissionModel);
    addPermissionForm.add(new DropDownChoice<String>("registrant", registrants));
    addPermissionForm.add(new DropDownChoice<AccessPermission>("permission", Arrays
        .asList(AccessPermission.NEWPERMISSIONS), new AccessPermissionRenderer(translations)));
    AjaxButton button = new AjaxButton("addPermissionButton", addPermissionForm) {

      private static final long serialVersionUID = 1L;

      @Override
      protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
        // add permission to our list
        RegistrantAccessPermission rp = (RegistrantAccessPermission) form.getModel().getObject();
        if (rp.permission == null) {
          return;
        }
        if (rp.registrant == null) {
          return;
        }
        RegistrantAccessPermission copy = DeepCopier.copy(rp);
        if (StringUtils.findInvalidCharacter(copy.registrant) != null) {
          copy.permissionType = PermissionType.REGEX;
          copy.source = copy.registrant;
        }
        permissions.add(copy);

        // resort permissions after insert to convey idea of eval order
        Collections.sort(permissions);

        // remove registrant from available choices
        registrants.remove(rp.registrant);

        // force the panel to refresh
        target.addComponent(RegistrantPermissionsPanel.this);
      }
    };
    addPermissionForm.add(button);

    // only show add permission form if we have a registrant choice
    add(addPermissionForm.setVisible(registrants.size() > 0));
  }

  @Override
  protected boolean getStatelessHint()
  {
    return false;
  }


  private class AccessPermissionRenderer implements IChoiceRenderer<AccessPermission> {

    private static final long serialVersionUID = 1L;

    private final Map<AccessPermission, String> map;

    public AccessPermissionRenderer(Map<AccessPermission, String> map) {
      this.map = map;
    }

    @Override
    public String getDisplayValue(AccessPermission type) {
      return map.get(type);
    }

    @Override
    public String getIdValue(AccessPermission type, int index) {
      return Integer.toString(index);
    }
  }

  private class ShowStateButton extends AjaxButton {
    private static final long serialVersionUID = 1L;

    Show buttonState;

    public ShowStateButton(String wicketId, Show state) {
      super(wicketId);
      this.buttonState = state;
      setOutputMarkupId(true);
    }

    @Override
    protected void onBeforeRender()
    {
      String cssClass = "btn";
      if (buttonState.equals(RegistrantPermissionsPanel.this.activeState)) {
        cssClass = "btn btn-info active";
      }
      WicketUtils.setCssClass(this, cssClass);
      super.onBeforeRender();
    }

    @Override
    protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
      RegistrantPermissionsPanel.this.activeState = buttonState;
      target.addComponent(RegistrantPermissionsPanel.this);
    }
  };
}
TOP

Related Classes of com.gitblit.wicket.panels.RegistrantPermissionsPanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.