# NetRightsEditor.java

    /*
    ** Module   : NetRightsEditor.java
    ** Abstract : Net rights editor.
    **
    ** Copyright (c) 2017, Golden Code Development Corporation.
    **
    ** -#- -I- --Date-- --------------------------------Description-----------------------------------
    ** 001 HC  20170612 Initial version.
    */
    /*
    ** This program is free software: you can redistribute it and/or modify
    ** it under the terms of the GNU Affero General Public License as
    ** published by the Free Software Foundation, either version 3 of the
    ** License, or (at your option) any later version.
    **
    ** This program 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 Affero General Public License for more details.
    **
    ** You may find a copy of the GNU Affero GPL version 3 at the following
    ** location: https://www.gnu.org/licenses/agpl-3.0.en.html
    **
    ** Additional terms under GNU Affero GPL version 3 section 7:
    **
    **   Under Section 7 of the GNU Affero GPL version 3, the following additional
    **   terms apply to the works covered under the License.  These additional terms
    **   are non-permissive additional terms allowed under Section 7 of the GNU
    **   Affero GPL version 3 and may not be removed by you.
    **
    **   0. Attribution Requirement.
    **
    **     You must preserve all legal notices or author attributions in the covered
    **     work or Appropriate Legal Notices displayed by works containing the covered
    **     work.  You may not remove from the covered work any author or developer
    **     credit already included within the covered work.
    **
    **   1. No License To Use Trademarks.
    **
    **     This license does not grant any license or rights to use the trademarks
    **     Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
    **     of Golden Code Development Corporation. You are not authorized to use the
    **     name Golden Code, FWD, or the names of any author or contributor, for
    **     publicity purposes without written authorization.
    **
    **   2. No Misrepresentation of Affiliation.
    **
    **     You may not represent yourself as Golden Code Development Corporation or FWD.
    **
    **     You may not represent yourself for publicity purposes as associated with
    **     Golden Code Development Corporation, FWD, or any author or contributor to
    **     the covered work, without written authorization.
    **
    **   3. No Misrepresentation of Source or Origin.
    **
    **     You may not represent the covered work as solely your work.  All modified
    **     versions of the covered work must be marked in a reasonable way to make it
    **     clear that the modified work is not originating from Golden Code Development
    **     Corporation or FWD.  All modified versions must contain the notices of
    **     attribution required in this license.
    */
    package com.goldencode.p2j.admin.client.editors;

    import com.goldencode.p2j.admin.client.widget.dialog.*;
    import com.goldencode.p2j.admin.client.widget.dialog.InputDialog.*;
    import com.goldencode.p2j.net.*;
    import com.goldencode.p2j.security.Description;
    import com.goldencode.p2j.security.*;
    import org.gwtbootstrap3.client.ui.*;

    import java.util.function.*;

    /**
     * Net rights editor.
     */
    public class NetRightsEditor
    implements RightsEditor
    {
       /** Description array */
       private Description[] description;

       /**
        * Returns the resource type name this editor is capable to edit.
        *
        * @return  see above
        */
       public static String getResourceType()
       {
          return "net";
       }

       /**
        * Gives chance to editors to initialize their data structures.
        * <p>
        * This is a one time call for this kind of resource for the life time
        * of the admin session.
        *
        * @param   description
        *          rights structure description
        */
       @Override
       public void initialize(Description[] description)
       {
          this.description = description;
       }

       /**
        * Creates an instance of the <code>Rights</code>, which does not take
        * any input and is considered a default starting point in editing.
        *
        * @return  an instance of <code>Rights</code>
        */
       @Override
       public Rights createDefaultRights()
       {
          return new NetRights();
       }

       /**
        * Edits the given instance of the <code>Rights</code>.
        * The implementation should prepare its modal dialog using the initial state
        * from the passed instance of the <code>Rights</code>, show the dialog,
        * provide event processing until the Save or Cancel action is applied, then
        * hide the dialog and return the appropriate result.
        *
        * @param   name
        *          name of the resource instance being edited
        * @param   exact
        *          nature of the name
        * @param   rights
        *          instance of <code>Rights</code> to be edited
        * @param   submitHandler
        *          Submit handler.
        * @param   cancelHandler
        *          Cancel handler.
        */
       @Override
       public void edit(String name,
                        boolean exact,
                        Rights rights,
                        Consumer<Rights> submitHandler,
                        Runnable cancelHandler)
       {
          String[] bitNames = description[0].getBitNames();

          BitSet perms = ((NetRights)rights).getPermissions();
          boolean denied = perms.isSet(NetRights.BIT_DENIED_ACCESS);

          RightsEditorContext ctxt = RightsEditorContext.instance();
          InputDialog dlg = ctxt.getInputDialog();

          // 1st row - Read permission
          Field[] fields = new Field[4];
          Field fRead = new Field("R (" + bitNames[0] + ")",
                                  perms.isSet(NetRights.BIT_READ_ACCESS) && !denied)
                        .withTooltip("allows seeing a remote method");
          fields[0] = fRead;

          // 2nd row - Write permission
          Field fWrite = new Field("W (" + bitNames[1] + ")",
                                  perms.isSet(NetRights.BIT_WRITE_ACCESS) && !denied)
                        .withTooltip("allows exporting a method for remote calls");
          fields[1] = fWrite;

          // 3rd row - Execute permission
          Field fExec = new Field("X (" + bitNames[2] + ")",
                                   perms.isSet(NetRights.BIT_EXECUTE_ACCESS) && !denied)
                         .withTooltip("allows calling a remote method");
          fields[2] = fExec;

          // 4th row - Denied access
          Field fDenied = new Field("N (" + bitNames[3] + ")", denied)
                          .withTooltip("denies any and all accesses");
          fields[3] = fDenied;

          dlg.build("Net Rights", fields);

          CheckBox readBox = (CheckBox) dlg.getWidget(fRead);
          CheckBox writeBox = (CheckBox) dlg.getWidget(fWrite);
          CheckBox execBox = (CheckBox) dlg.getWidget(fExec);
          CheckBox deniedBox = (CheckBox) dlg.getWidget(fDenied);
          Consumer<Boolean> updateBoxes = val ->
          {
             readBox.setEnabled(val);
             writeBox.setEnabled(val);
             execBox.setEnabled(val);
          };

          updateBoxes.accept(!denied);

          deniedBox.addValueChangeHandler(event ->
          {
             boolean val = event.getValue();
             updateBoxes.accept(!val);
          });

          dlg.show(ctxt.getParent(), vals ->
          {
             if (vals != null)
             {
                boolean readVal = (Boolean) vals.get(fRead);
                boolean writeVal = (Boolean) vals.get(fWrite);
                boolean execVal = (Boolean) vals.get(fExec);
                boolean deniedVal = (Boolean) vals.get(fDenied);

                perms.set(NetRights.BIT_READ_ACCESS, readVal && !deniedVal);
                perms.set(NetRights.BIT_WRITE_ACCESS, writeVal && !deniedVal);
                perms.set(NetRights.BIT_EXECUTE_ACCESS, execVal && !deniedVal);
                perms.set(NetRights.BIT_DENIED_ACCESS, deniedVal);

                submitHandler.accept(new NetRights(perms));
             }
             else
             {
                cancelHandler.run();
             }
          });
       }
    }