Unix Rights Helper

UnixRightsHelper.png

Screenshot

Use checkboxes to assemble UNIX rights as string and octal values.

/*
 * Copyright (c) 2002, 2003, 2009 Jochen Kupperschmidt
 * Released under the terms of the MIT License
 *    _                               _
 *   | |_ ___ _____ ___ _ _ _ ___ ___| |_
 *   |   | . |     | ._| | | | . |  _| . /
 *   |_|_|___|_|_|_|___|_____|___|_| |_|_\
 *     http://homework.nwsnet.de/
 *
 * The user is presented a window with checkboxes that allows to select UNIX
 * file permissions for user/group/others and displays the respective string
 * and octal value representations.
 *
 * It began as an exercise to gain more experience with Java and Swing
 * programming, but might also prove useful to people learning UNIX-like
 * operating systems or in need of a dialog to graphically change file
 * permissions, e.g. for creating an FTP client.
 *
 * This is the Groovy remake (27-Dec-2009) of the original Java application
 * (20-Mar-2003).  It makes extensive use of Groovy features (implicit getters
 * and setters, closures, the asterisk operator, maps as constructor arguments,
 * SwingBuilder) and thus requires significantly less code.
 */

import groovy.swing.SwingBuilder
import java.awt.BorderLayout
import java.awt.Font
import java.awt.GridLayout
import javax.swing.JCheckBox
import javax.swing.JFrame
import javax.swing.JLabel
import javax.swing.JPanel

/**
 * A representation of UNIX file permissions (read, write, execute).
 */
class Permissions {

  def final chars = ['x', 'w', 'r']
  def flags = new BitSet(chars.size())

  def assemble(Closure closure, notSetValue) {
    (0..<chars.size()).collect {flags[it] ? closure(it) : notSetValue}.sum()
  }

  def getStringValue() {
    assemble({chars[it]}, '-').reverse()
  }

  def getOctalValue() {
    assemble({1 << it}, 0) as int
  }
}

/**
 * A panel with checkboxes to select UNIX file permissions.
 */
class PermissionsPanel extends JPanel {

  def permissions = new Permissions()

  def PermissionsPanel(Closure actionHandler) {
    layout = new GridLayout(0, 1)
    [2: 'Read', 1: 'Write', 0: 'Execute'].each {i, label ->
      def checkbox = new JCheckBox(focusPainted: false, text: label)
      checkbox.actionPerformed = {
        // Update permissions from checkbox state.
        permissions.flags[i] = checkbox.selected

        actionHandler()
      }
      add(checkbox)
    }
  }
}

def List<PermissionsPanel> permissionsPanels = []
def displayLabels = []

def updatePermissionsDisplay = {
  // Update string and octal representations.
  displayLabels[0].text = permissionsPanels*.permissions*.stringValue.join('')
  displayLabels[1].text = permissionsPanels*.permissions*.octalValue.join('')
  println displayLabels*.text.join('  ')
}

def swing = new SwingBuilder()
swing.lookAndFeel('gtk')
swing.frame(defaultCloseOperation: JFrame.EXIT_ON_CLOSE,
    locationRelativeTo: null, pack: true, resizable: false, show: true,
    title: 'Unix Rights Helper') {
  panel(border: emptyBorder(4)) {
    borderLayout()

    // Create permission selection panels.
    panel(constraints: BorderLayout.CENTER) {
      gridLayout(cols: 0, rows: 1)

      ['User', 'Group', 'Others'].each {title ->
        def permissionsPanel = new PermissionsPanel(updatePermissionsDisplay)
        permissionsPanel.border = titledBorder(title)
        widget(permissionsPanel)
        permissionsPanels << permissionsPanel
      }
    }

    // Create permission representation panels.
    panel(constraints: BorderLayout.SOUTH) {
      gridLayout(cols: 0, rows: 1)

      ['String', 'Octal'].each {title ->
        panel(border: titledBorder(title)) {
          def displayLabel = label(font: new Font('Monospaced', Font.PLAIN, 12),
              horizontalAlignment: JLabel.CENTER)
          widget(displayLabel)
          displayLabels << displayLabel
        }
      }
    }
  }

  // Initialize display permissions.
  updatePermissionsDisplay()
}