Received: from SOUTH-STATION-ANNEX.MIT.EDU by po10.MIT.EDU (5.61/4.7) id AA16813; Wed, 14 Jul 99 05:56:57 EDT
Received: from hermes.javasoft.com by MIT.EDU with SMTP
	id AA20245; Wed, 14 Jul 99 05:52:26 EDT
Received: by hermes.java.sun.com (SMI-8.6/SMI-SVR4)
	id KAA23098; Wed, 14 Jul 1999 10:21:07 GMT
Date: Wed, 14 Jul 1999 10:21:07 GMT
Message-Id: <199907141021.KAA23098@hermes.java.sun.com>
X-Mailing: 130
From: JDCTechTips@sun.com
Subject: JDC Tech Tips July, 1999
To: JDCMember@sun.com
Reply-To: JDCTechTips@sun.com
Errors-To: JDCMailErrors@sun.com
Precedence: junk
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
X-Mailer: Beyond Email 2.1


 J  D  C    T  E  C  H    T  I  P  S

                      TIPS, TECHNIQUES, AND SAMPLE CODE


WELCOME to the Java Developer Connection(sm) (JDC) Tech Tips, 
July 13, 1999. This issue covers:

         * Undoing Text Edits
         * Adding Security Features to Applications


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
UNDOING TEXT EDITS

A new feature in Java Foundation Classes (JFC) Project Swing is the 
ability to undo text edits. For example, suppose you have a 
JTextArea that you use in some application. You might want to keep 
track of user edits to the text area, and then possibly undo some 
of them to change the content of the area back to some previous 
state.

Consider the following example that uses undo:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.undo.*;
    
    public class undo {
        static UndoManager undomanager;
    
        static class UndoHandler implements UndoableEditListener {
            public void undoableEditHappened(UndoableEditEvent e) {
                if (undomanager != null) {
                    undomanager.addEdit(e.getEdit());
                    //System.out.println(e.getEdit());
                }
            }
        }
    
        public static void main(String args[]) {
            // set up frames, panels, text areas
            JFrame frame = new JFrame("Undo demo");
            frame.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }
            });
            JPanel panel = new JPanel();
            panel.setLayout(new BorderLayout());
            final JTextArea textarea = new JTextArea(10, 40);
            JPanel textpanel = new JPanel();
            textpanel.add(new JScrollPane(textarea));
            textarea.getDocument().addUndoableEditListener(
                new UndoHandler());
    
            // create buttons and set up listeners for them
            JPanel buttonpanel = new JPanel();
            JButton startbutton = new JButton("Start Edits");
            JButton undobutton = new JButton("Undo Edits");
            startbutton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    undomanager = new UndoManager();
                    undomanager.setLimit(1000);
                    textarea.requestFocus();
                }
            });
            undobutton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    if (undomanager != null) {
                        undomanager.end();
                        undomanager.undo();
                        undomanager = null;
                    }
                    else {
                        Toolkit.getDefaultToolkit().beep();
                    }
                    textarea.requestFocus();
                }
            });
            buttonpanel.add(startbutton);
            buttonpanel.add(undobutton);
            panel.add("North", textpanel);
            panel.add("South", buttonpanel);
    
            // make frame visible
            frame.getContentPane().add("Center", panel);
            frame.pack();
            frame.setVisible(true);
        }
    }

The example sets up a JTextArea in the usual way, and then adds an
UndoableEditListener to the area's underlying Document object. This
has the effect of setting up a listener for all document edits. For
example, if a character is added to the text area, this constitutes
an edit, and the listener is notified.

An object of the UndoManager class is used to collect edits. This
object is set up when the Start Edits button is selected, and then
edits are accumulated. An edit limit of 1000 is set, meaning that
at most 1000 edits are accumulated in the UndoManager object. If
you uncomment the "System.out.println" statement in the example, 
you can look at a description of each edit as it comes in.

When Undo Edits is selected, all of the accumulated edits are
undone. For example, suppose that you enter the letters "abc" into
the text area, then select Start Edits, then add, delete, cut,
copy, and paste text at will, and then select Undo Edits. This
sequence puts you back where you started, with only "abc" in
the text area. It is also possible to redo undone edits using the
"redo" method of UndoManager.

You can use undo/redo in other areas besides text. The UndoableEdit
interface and the AbstractUndoableEdit class provide a framework 
for undo support, and can be applied in a variety of contexts.

ADDING SECURITY FEATURES TO APPLICATIONS

Java(tm) security has many aspects to it, and in this tip, we 
illustrate one simple technique for adding security features to 
applications. This technique demonstrates how permissions in a 
central policy file can be used to enable application features. 
Note that this tip assumes the standard Java 2 default security 
setup, which may have been modified in your local environment.

The first thing to look at is a dummy application:

    import java.security.*;
    import local.*;
    
    public class perm {
        public static void main(String args[]) {
            MyPermission myp = new MyPermission("perm1");
            try {
                AccessController.checkPermission(myp);
                System.out.println("Permission granted");
            }
            catch (AccessControlException e) {
                System.out.println("Permission denied");
            }
        }
    }

MyPermission is a class, and "myp" an object of that class. The myp 
object represents a permission, that is, something that the 
application is allowed to do. This class resides in a package called 
"local" somewhere on your local system. The class itself looks like 
this:

    package local;

    import java.security.*;

    public class MyPermission extends BasicPermission {
        public MyPermission(String s) {super(s);}
        public MyPermission(String s, String t) {super(s, t);}
    }

The class simply defines a couple of constructors, that pass through
their arguments to the superclass, java.security.BasicPermission.

So there is an object of a local permission type, representing some
local policy. AccessController.checkPermission is called with this
object as its argument, and it throws an AccessControlException if
access is not granted. By default this application will print
"Permission denied", that is, the permission "perm1" for the
permission class "MyPermission" is denied.

But how does checkPermission know whether a permission should be
allowed or denied?  In the default security setup, permissions are
declared in the file:

    jre/lib/security/java.policy

under the installation root, and the "master security properties
file" is:

    jre/lib/security/java.security

If you add a line to java.policy just after "grant {", like this:

    grant {
        permission local.MyPermission "perm1";

then you've enabled this permission locally.

But it's more complicated than simply editing this file. You might
not have the right to edit a central policy file on your local 
system. So the security properties file allows an administrator to 
specify which policy files are checked, with the default being:

    policy.url.1=file:${java.home}/lib/security/java.policy
    policy.url.2=file:${user.home}/.java.policy

In other words, the central file is checked, along with a file you
have control over in your home directory. If you want to run
the above example without editing jre/lib/security/java.policy, 
you can instead create a file, ".java.policy", in your home 
directory. Here is the content of the local .java.policy file:

    grant { 
        permission local.MyPermission "perm1";
    };

This feature does not advance the enforcement of centralized 
policies. So an administrator may disable the line in the 
java.security file that allows for checking of local policy files.

Another aspect of specifying policy files is the default feature
that allows specification of a policy file on the command line:

    java -Djava.security.policy=pathname

The line in the java.security file that reads:

    policy.allowSystemProperty=true

can be toggled to "false" to disallow this type of override.

.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .

- NOTE
The names on the JDC mailing list are used for internal Sun
Microsystems(tm) purposes only.  To remove your name from the list,
see Subscribe/Unsubscribe below.


- FEEDBACK
Comments?  Send your feedback on the JDC Tech Tips to:

JDCTechTips@Sun.com


- SUBSCRIBE/UNSUBSCRIBE
The JDC Tech Tips are sent to you because you elected to subscribe
when you registered as a JDC member.  To unsubscribe from JDC Email,
go to the following address and enter the email address you wish to
remove from the mailing list:

http://developer.java.sun.com/unsubscribe.html


To become a JDC member and subscribe to this newsletter go to:

http://java.sun.com/jdc/


- ARCHIVES
You'll find the JDC Tech Tips archives at:

http://developer.java.sun.com/developer/TechTips/index.html


- COPYRIGHT
Copyright 1999 Sun Microsystems, Inc. All rights reserved.
901 San Antonio Road, Palo Alto, California 94303 USA.

This document is protected by copyright.  For more information, see:

http://developer.java.sun.com/developer/copyright.html


The JDC Tech Tips are written by Glen McCluskey.

JDC Tech Tips 
July 13, 1999










