Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/Main.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/Main.java (revision 674165) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/Main.java (working copy) @@ -20,14 +20,14 @@ import org.apache.harmony.tools.policytool.view.MainFrame; /** - * The main class that parses command line parameters, and starts the - * GUI if everything everything is ok. + * The main class that parses command line parameters, and starts the GUI if everything everything is ok. + * */ public class Main { - + /** Name of policy file to be loaded initially. */ private static String policyFileName; - + /** * Entry point of the program. * @@ -34,7 +34,7 @@ * @param arguments used to take arguments from the running environment */ public static void main( final String[] arguments ) { - + if ( processArguments( arguments ) ) { if ( policyFileName == null ) new MainFrame().setVisible( true ); @@ -41,9 +41,9 @@ else new MainFrame( policyFileName ).setVisible( true ); } - + } - + /** * Processes the command line arguments.
* Currently only one option is supported: @@ -57,7 +57,7 @@ private static boolean processArguments( final String[] arguments ) { if ( arguments.length == 0 ) return true; - + else { if ( arguments[ 0 ].startsWith( "-" ) ) // If it is a "real" option if ( arguments[ 0 ].equalsIgnoreCase( "-file" ) ) { @@ -64,21 +64,23 @@ if ( arguments.length < 2 ) { // policy file name must be provided printErrorMessageAndUsage( "Missing policy file name!" ); return false; - } else { + } + else { policyFileName = arguments[ 1 ]; return true; } - } else { + } + else { printErrorMessageAndUsage( "Illegal option: " + arguments[ 0 ] ); return false; - } else - return true; // else the arguments are ignored + } + else + return true; // else the arguments are ignored } } - + /** - * Prints an error message to the standard output followed by the - * program ussage. + * Prints an error message to the standard output followed by the program ussage. * @param errorMessage error message to be printed */ private static void printErrorMessageAndUsage( final String errorMessage ) { @@ -85,7 +87,7 @@ System.out.println( errorMessage ); printUsage(); } - + /** * Prints the program usage to the standard output. */ @@ -94,5 +96,5 @@ System.out.println(); System.out.println( " [-file ] name of policy file to be loaded initially" ); } - + } Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/GrantEntry.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/GrantEntry.java (revision 0) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/GrantEntry.java (revision 0) @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.harmony.tools.policytool.model; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents an entry which specifies some grant permission. + */ +public class GrantEntry extends PolicyEntry { + + /** Keyword of the keystore entry in the policy text. */ + public static final String KEYWORD = "grant"; + + /** Code base of the grant entry. */ + private String codeBase; + /** Signed by alias (from the keystore). */ + private String signedBy; + + /** List of principals of the entry. */ + private List< Principal > principalList = new ArrayList< Principal >(); + /** List of permissions of the entry. */ + private List< Permission > permissionList = new ArrayList< Permission >(); + + /** + * Returns the code base of the entry. + * @return the code base of the entry + */ + public String getCodeBase() { + return codeBase; + } + + /** + * Sets the code base of the entry. + * @param codeBase the code base of the entry + */ + public void setCodeBase( final String codeBase ) { + this.codeBase = codeBase; + } + + /** + * Returns the signed by alias of the entry. + * @return the signed by alias of the entry + */ + public String getSignedBy() { + return signedBy; + } + + /** + * Returns the signed by alias of the entry. + * @param signedBy the signed by alias of the entry to be set + */ + public void setSignedBy( final String signedBy ) { + this.signedBy = signedBy; + } + + /** + * Returns the list of principals of the entry. + * @return the list of principals of the entry + */ + public List< Principal > getPrincipalList() { + return principalList; + } + + /** + * Sets the list of principals of the entry. + * @param principalList list of principals of the entry to be set + */ + public void setPrincipalList( final List< Principal > principalList ) { + this.principalList = principalList; + } + + /** + * Returns the list of permissions of the entry. + * @return the list of permissions of the entry + */ + public List< Permission > getPermissionList() { + return permissionList; + } + + /** + * Sets the list of permissions of the entry. + * @param permissionList list of permissions of the entry to be set + */ + public void setPermissionList( final List< Permission > permissionList ) { + this.permissionList = permissionList; + } + + @Override + public String getText() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setText( final String entryText ) { + // TODO Auto-generated method stub + } + +} Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/PolicyEntry.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/PolicyEntry.java (revision 674165) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/PolicyEntry.java (working copy) @@ -21,10 +21,10 @@ * Abstract ancestor to represent a policy entry. */ public abstract class PolicyEntry { - + /** Terminator character of the policy entry texts. */ public static final char TERMINATOR_CHAR = ';'; - + /** * Returns the policy entry text. * @return the policy entry text @@ -30,7 +30,7 @@ * @return the policy entry text */ public abstract String getText(); - + /** * Sets the policy entry text. * @param entryText policy entry text to be set @@ -36,5 +36,5 @@ * @param entryText policy entry text to be set */ public abstract void setText( final String entryText ); - + } Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/Permission.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/Permission.java (revision 0) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/Permission.java (revision 0) @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.harmony.tools.policytool.model; + +/** + * Represents a principal for the grant entries. + */ +public class Permission { + + /** Name of the class of the permission. */ + private String className; + /** Name of target of the permission. */ + private String targetName; + /** Actions of the permission. */ + private String actions; + /** Signed by alias of the permission (from the keystore). */ + private String signedBy; + + /** + * Returns the name of the class of the permission. + * @return the name of the class of the permission + */ + public String getClassName() { + return className; + } + + /** + * Sets the name of the class of the permission. + * @param className the name of the class of the permission to be set + */ + public void setClassName( final String className ) { + this.className = className; + } + + /** + * Returns the name of target of the permission. + * @return the name of target of the permission + */ + public String getTargetName() { + return targetName; + } + + /** + * Sets the name of target of the permission + * @param targetName the name of target of the permission to be set + */ + public void setTargetName( final String targetName ) { + this.targetName = targetName; + } + + /** + * Returns the actions of the permission. + * @return the actions of the permission + */ + public String getActions() { + return actions; + } + + /** + * Sets the actions of the permission + * @param actions actions of the permission to be set + */ + public void setActions( final String actions ) { + this.actions = actions; + } + + /** + * Returns the signed by alias of the permission. + * @return the signed by alias of the permission + */ + public String getSignedBy() { + return signedBy; + } + + /** + * Returns the signed by alias of the permission. + * @param signedBy the signed by alias of the permission to be set + */ + public void setSignedBy( final String signedBy ) { + this.signedBy = signedBy; + } + +} Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/Principal.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/Principal.java (revision 0) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/Principal.java (revision 0) @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.harmony.tools.policytool.model; + +/** + * Represents a principal for the grant entries. + */ +public class Principal { + + /** Type of the principal. */ + private String type; + /** Name of the principal. */ + private String name; + + /** + * Returns the type. + * @return the type + */ + public String getType() { + return type; + } + + /** + * Sets the type of the principal. + * @param type type of the principal to be set + */ + public void setType( final String type ) { + this.type = type; + } + + /** + * Returns the name of the principal. + * @return the name of the principal + */ + public String getName() { + return name; + } + + /** + * Sets the name of the principal. + * @param name name of the principal to be set + */ + public void setName( final String name ) { + this.name = name; + } + +} Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/KeystoreEntry.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/KeystoreEntry.java (revision 674165) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/KeystoreEntry.java (working copy) @@ -28,10 +28,10 @@ * @see KeystorePasswordURLEntry */ public class KeystoreEntry extends PolicyEntry { - + /** Keyword of the keystore entry in the policy text. */ public static final String KEYWORD = "keystore"; - + /** URL of the keystore. */ private String url; /** Type of the keystore. */ @@ -38,7 +38,55 @@ private String type; /** Provider of the keystore. */ private String provider; - + + /** + * Returns the keystore url. + * @return the keystore url + */ + public String getUrl() { + return url; + } + + /** + * Sets the keystore url. + * @param url keystore url to be set + */ + public void setUrl( final String url ) { + this.url = url; + } + + /** + * Returns the keystore type. + * @return the keystore type + */ + public String getType() { + return type; + } + + /** + * Sets the keystore type. + * @param type keystore type to be set + */ + public void setType( final String type ) { + this.type = type; + } + + /** + * Returns the keystore provider. + * @return the keystore provider + */ + public String getProvider() { + return provider; + } + + /** + * sets the keystore provider. + * @param provider keystore provider to be set + */ + public void setProvider( final String provider ) { + this.provider = provider; + } + @Override public String getText() { final StringBuilder textBuilder = new StringBuilder( KEYWORD ); @@ -43,7 +91,7 @@ public String getText() { final StringBuilder textBuilder = new StringBuilder( KEYWORD ); boolean firstParamAdded = false; - + if ( url != null ) { textBuilder.append( " \"" ).append( url ).append( '"' ); firstParamAdded = true; @@ -48,7 +96,7 @@ textBuilder.append( " \"" ).append( url ).append( '"' ); firstParamAdded = true; } - + if ( type != null ) { if ( firstParamAdded ) textBuilder.append( ',' ); @@ -56,7 +104,7 @@ firstParamAdded = true; textBuilder.append( " \"" ).append( type ).append( '"' ); } - + if ( provider != null ) { if ( firstParamAdded ) textBuilder.append( ',' ); @@ -64,12 +112,12 @@ firstParamAdded = true; textBuilder.append( " \"" ).append( provider ).append( '"' ); } - + textBuilder.append( TERMINATOR_CHAR ); - + return textBuilder.toString(); } - + @Override public void setText( final String entryText ) { // TODO Auto-generated method stub @@ -74,5 +122,5 @@ public void setText( final String entryText ) { // TODO Auto-generated method stub } - + } Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/KeystorePasswordURLEntry.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/KeystorePasswordURLEntry.java (revision 674165) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/KeystorePasswordURLEntry.java (working copy) @@ -26,13 +26,29 @@ * @see KeystoreEntry */ public class KeystorePasswordURLEntry extends PolicyEntry { - + /** Keyword of the keystore password URL entry in the policy text. */ public static final String KEYWORD = "keystorePasswordURL"; - + /** URL of the keystore password. */ private String url; - + + /** + * Returns the keystore password url. + * @return the keystore password url + */ + public String getUrl() { + return url; + } + + /** + * Sets the keystore password URL + * @param url the keystore password URL to be set + */ + public void setUrl( final String url ) { + this.url = url; + } + @Override public String getText() { return KEYWORD + " \"" + url + '\"' + TERMINATOR_CHAR; @@ -37,7 +53,7 @@ public String getText() { return KEYWORD + " \"" + url + '\"' + TERMINATOR_CHAR; } - + @Override public void setText( final String entryText ) { // TODO Auto-generated method stub @@ -42,5 +58,5 @@ public void setText( final String entryText ) { // TODO Auto-generated method stub } - + } Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/CommentEntry.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/CommentEntry.java (revision 674165) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/model/CommentEntry.java (working copy) @@ -26,10 +26,10 @@ * */ public class CommentEntry extends PolicyEntry { - + /** Comment entries are not tokenized just holds the entry text "as is". */ private String entryText; - + /** * Creates a new CommentEntry. * @param entryText policy entry text of the entry @@ -37,7 +37,7 @@ public CommentEntry( final String entryText ) { setText( entryText ); } - + @Override public String getText() { return entryText; @@ -42,7 +42,7 @@ public String getText() { return entryText; } - + @Override public void setText( final String entryText ) { this.entryText = entryText; @@ -47,5 +47,5 @@ public void setText( final String entryText ) { this.entryText = entryText; } - + } Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/BaseFormDialog.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/BaseFormDialog.java (revision 0) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/BaseFormDialog.java (revision 0) @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.harmony.tools.policytool.view; + +import java.awt.BorderLayout; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JPanel; + +/** + * Represents a base form dialog which will be used to query data of policy entries. + */ +public abstract class BaseFormDialog extends JDialog implements ActionListener { + + /** Reference to the owner frame. */ + private final Frame ownerFrame; + + /** Ok button of the form dialog. */ + private final JButton okButton = new JButton( "OK" ); + /** Cancel button of the form dialog. */ + private final JButton cancelButton = new JButton( "Cancel" ); + + /** Reference to the owner editor panel. This reference can (will) be used to indicate new data/dirty state. */ + protected final EditorPanel ownerEditorPanel; + + /** + * Creates a new BaseFormDialog. + * @param ownerFrame owner frame of the dialog + * @param title title of the dialog + * @param ownerEditorPanel reference to the owner editor panel + */ + public BaseFormDialog( final Frame ownerFrame, final String title, final EditorPanel ownerEditorPanel ) { + super( ownerFrame, title, true ); + + this.ownerFrame = ownerFrame; + this.ownerEditorPanel = ownerEditorPanel; + + buildBaseGUI(); + setDefaultCloseOperation( DISPOSE_ON_CLOSE ); + } + + /** + * Builds the graphical user interface of the base dialog.
+ * Adds a button panel to the bottom of the dialog containing an ok and a cancel button. + */ + protected void buildBaseGUI() { + final JPanel panel = new JPanel(); + + okButton.setMnemonic( okButton.getText().charAt( 0 ) ); + okButton.addActionListener( this ); + panel.add( okButton ); + + cancelButton.setMnemonic( cancelButton.getText().charAt( 0 ) ); + cancelButton.addActionListener( this ); + panel.add( cancelButton ); + + add( panel, BorderLayout.SOUTH ); + } + + /** + * Centers the dialog to its owner frame. + */ + public void center() { + setLocation( ownerFrame.getX() + ownerFrame.getWidth () / 2 - getWidth () / 2, + ownerFrame.getY() + ownerFrame.getHeight() / 2 - getHeight() / 2 ); + } + + /** + * Handles the action events of the dialog's ok and cancel button. + */ + public void actionPerformed( final ActionEvent ae ) { + if ( ae.getSource() == okButton ) + onOkButtonPressed(); + if ( ae.getSource() == cancelButton ) + onCancelButtonPressed(); + } + + /** + * Called when the ok button of the dialog is pressed. + */ + public abstract void onOkButtonPressed(); + + /** + * Called when the cancel button of the dialog is pressed.
+ * Simply disposes the dialog. + */ + public void onCancelButtonPressed() { + dispose(); + } + +} Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/GraphicalEditorPanel.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/GraphicalEditorPanel.java (revision 674165) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/GraphicalEditorPanel.java (working copy) @@ -18,45 +18,76 @@ package org.apache.harmony.tools.policytool.view; import java.awt.BorderLayout; +import java.util.ArrayList; import java.util.List; +import org.apache.harmony.tools.policytool.model.GrantEntry; +import org.apache.harmony.tools.policytool.model.KeystoreEntry; +import org.apache.harmony.tools.policytool.model.KeystorePasswordURLEntry; import org.apache.harmony.tools.policytool.model.PolicyEntry; /** - * An editor panel which provides an interface for direct editing the - * policy text. + * An editor panel which provides an interface for direct editing the policy text. */ public class GraphicalEditorPanel extends EditorPanel { - - /** Holds the invalid policy text or null if the loaded policy - * text is valid. */ - private String invalidPolicyText; - - /** The list of the policy text's entries or null if invalid - * policy text was loaded. */ - private List< PolicyEntry > policyEntryList; - + + /** Holds the invalid policy text or null if the loaded policy text is valid. */ + private String invalidPolicyText; + + /** The list of the policy text's entries or null if invalid policy text was loaded. */ + private List< PolicyEntry > policyEntryList = new ArrayList< PolicyEntry >(); + /** * Creates a new GraphicalEditorPanel.
* Sets a BorderLayout as the layout manager. + * @param mainFrame reference to the main frame */ - public GraphicalEditorPanel() { - super( new BorderLayout(), true ); - } - - @Override - public String getPanelTitle() { - return "Graphical editing"; + public GraphicalEditorPanel( final MainFrame mainFrame ) { + super( mainFrame, "Graphical editing", new BorderLayout(), true ); + + // buildGUI: + add( new ListAndEditPanel< PolicyEntry >( "Policy Entry", policyEntryList, new ListAndEditPanel.Filter< PolicyEntry > () { + public boolean includeEntity( final PolicyEntry entity ) { + return entity instanceof GrantEntry; + } + } ), BorderLayout.CENTER ); } - + @Override - public void loadPolicyText( final String policyText ) { + public boolean loadPolicyText( final String policyText ) { this.invalidPolicyText = policyText; + + policyEntryList = new ArrayList< PolicyEntry >(); + + return true; } - + @Override - public String getPolicyText() { + public String getPolicyText() { return invalidPolicyText; } - + + /** + * Shows the keystore entry edit dialog.
+ * This dialog handles both the keystore entry and the keystore password URL entries. + */ + public void showKeystoreEntryEditDialog() { + KeystoreEntry keystoreEntry = null; + KeystorePasswordURLEntry keystorePasswordURLEntry = null; + + for ( final PolicyEntry policyEntry : policyEntryList ) { + if ( keystoreEntry == null ) + if ( policyEntry instanceof KeystoreEntry ) + keystoreEntry = (KeystoreEntry) policyEntry; + if ( keystorePasswordURLEntry == null ) + if ( policyEntry instanceof KeystorePasswordURLEntry ) + keystorePasswordURLEntry = (KeystorePasswordURLEntry) policyEntry; + + if ( keystoreEntry != null && keystorePasswordURLEntry != null ) + break; + } + + new KeystoreEntryEditFormDialog( mainFrame, this, keystoreEntry, keystorePasswordURLEntry, policyEntryList ).setVisible( true ); + } + } Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/ListAndEditPanel.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/ListAndEditPanel.java (revision 0) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/ListAndEditPanel.java (revision 0) @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.harmony.tools.policytool.view; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.List; + +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +/** + * The abstraction of a panel which can list entities and provide GUI components to offer and handle certain actions on the entities.
+ * The entities are listed in a listbox, + * @param type of the entities listed on and edited by this panel + */ +public class ListAndEditPanel< EntityType > extends JPanel implements ActionListener { + + /** The component to list he entities. */ + private final JList entityListComponent = new JList(); + + /** Add new entity button. */ + private final JButton addButton = new JButton(); + /** Edit selected entity button. */ + private final JButton editButton = new JButton(); + /** Remove selected entity button. */ + private final JButton removeButton = new JButton(); + + /** Reference to the list whose elements are to be listed and edited, and where to put new entities. */ + private final List< ? > entityList; + + /** + * Can be used to filter the input entity list, hide elements from displaying. + * @param type of the entities filtered by this filter + */ + public interface Filter< EntityType > { + /** + * Tells whether to include an entity in the list-and-edit process + * @param entity entity to be tested + * @return true if the entity should be listed and edited; false if it should be and excluded and hid + */ + boolean includeEntity( final EntityType entity ); + } + + /** + * Creates a new ListAndEditPanel.
+ * Sets a BorderLayout for ourselves. + * @param entityName name of the listed and edited entity (this will be displayed on the buttons) + * @param entityList reference to the list whose elements are to be listed and edited, and where to put new entities + */ + public ListAndEditPanel( final String entityName, final List< EntityType > entityList ) { + this( entityName, entityList, null ); + } + + /** + * Creates a new ListAndEditPanel.
+ * Sets a BorderLayout for ourselves. + * @param entityName name of the listed and edited entity (this will be displayed on the buttons) + * @param entityList reference to the list whose elements are to be listed and edited, and where to put new entities + * @param entityFilter filter to be used when listing the entities + */ + public ListAndEditPanel( final String entityName, final List< EntityType > entityList, final Filter< EntityType > entityFilter ) { + super( new BorderLayout() ); + + this.entityList = entityList; + + final DefaultListModel listModel = new DefaultListModel(); + for ( final EntityType entity : entityList ) + if ( entityFilter == null || entityFilter.includeEntity( entity ) ) + listModel.addElement( entity ); + + entityListComponent.setModel( listModel ); + + buildGUI( entityName ); + } + + /** + * Builds the graphical user interface of the panel. + * @param entityName name of the listed and edited entity (this will be displayed on the buttons) + */ + private void buildGUI( final String entityName ) { + final JPanel buttonsPanel = new JPanel(); + + addButton .setText ( "Add " + entityName ); + addButton .setMnemonic ( addButton .getText().charAt( 0 ) ); + addButton .addActionListener( this ); + buttonsPanel.add( addButton ); + + editButton .setText ( "Edit " + entityName ); + editButton .setMnemonic ( editButton .getText().charAt( 0 ) ); + editButton .addActionListener( this ); + buttonsPanel.add( editButton ); + + removeButton.setText ( "Remove " + entityName ); + removeButton.setMnemonic ( removeButton.getText().charAt( 0 ) ); + removeButton.addActionListener( this ); + buttonsPanel.add( removeButton ); + + add( buttonsPanel, BorderLayout.NORTH ); + + add( new JScrollPane( entityListComponent ), BorderLayout.CENTER ); + } + + /** + * Handles the action events of the buttons for adding new, editing and removing entities. + * @param ae details of the action event + */ + public void actionPerformed( final ActionEvent ae ) { + } + +} Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/MainFrame.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/MainFrame.java (revision 674165) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/MainFrame.java (working copy) @@ -6,13 +6,13 @@ * (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 + * 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. + * 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 org.apache.harmony.tools.policytool.view; @@ -20,12 +20,17 @@ import java.awt.BorderLayout; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.io.File; +import java.io.IOException; import javax.swing.JFrame; +import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; +import javax.swing.JPanel; import javax.swing.JTabbedPane; +import javax.swing.JTextField; import org.apache.harmony.tools.policytool.Consts; import org.apache.harmony.tools.policytool.control.Controller; @@ -34,7 +39,10 @@ * This is the main frame of policytool. */ public class MainFrame extends JFrame { - + + /** Text field to display the current policy file. */ + private final JTextField policyFileDisplayerTextField = new JTextField(); + /** * Creates a new MainFrame with no initial poilcy file. */ @@ -41,7 +49,7 @@ public MainFrame() { this( null ); } - + /** * Creates a new MainFrame. * @param policyFileName policy file name to be loaded initially @@ -48,22 +56,22 @@ */ public MainFrame( final String policyFileName ) { super( Consts.APPLICATION_NAME ); - - final EditorPanel[] editorPanels = new EditorPanel[] { new GraphicalEditorPanel(), new DirectTextEditorPanel() }; + + final EditorPanel[] editorPanels = new EditorPanel[] { new GraphicalEditorPanel( this ), new DirectTextEditorPanel( this ) }; final Controller controller = new Controller( this, editorPanels, policyFileName ); - + buildGUI( controller ); - + setLocation( Consts.MAIN_FRAME_START_POS_X, Consts.MAIN_FRAME_START_POS_X ); - setSize( 400, 400 ); + setSize( 500, 500 ); setDefaultCloseOperation( DO_NOTHING_ON_CLOSE ); addWindowListener( new WindowAdapter() { - public void windowClosing( final WindowEvent we ) { - controller.exit(); - } - } ); + public void windowClosing( final WindowEvent we ) { + controller.exit(); + } + } ); } - + /** * Builds the graphical user interface of the main frame. * @param controller reference to the controller @@ -70,9 +78,17 @@ */ private void buildGUI( final Controller controller ) { buildMenusAndMenuBar( controller ); - buildTabbedPane ( controller ); + + final JPanel panel = new JPanel( new BorderLayout( 5, 0 ) ); + panel.add( new JLabel( " Policy file:" ), BorderLayout.WEST ); + + policyFileDisplayerTextField.setEditable( false ); + panel.add( policyFileDisplayerTextField, BorderLayout.CENTER ); + add( panel, BorderLayout.NORTH ); + + buildTabbedPane( controller ); } - + /** * Menu items of policytool. */ @@ -79,23 +95,23 @@ public static enum MenuItemEnum { /** File menu */ FILE ( true, "File" ), - /** New menu item */ - NEW ( "New" ), - /** Save menu item */ - OPEN ( "Open" ), - /** Save menu item */ - SAVE ( "Save" ), - /** Save as menu item */ - SAVE_AS ( "Save As...", 'a' ), - /** View warning log menu item */ - VIEW_WARNING_LOG( "View Warning Log" ), - /** Exit menu item */ - EXIT ( "Exit", 'x' ), - /** KeyStore menu */ - KEY_STORE ( true, "KeyStore" ), - /** Edit menu item */ - EDIT ( "Edit" ); - + /** New menu item */ + NEW ( "New" ), + /** Save menu item */ + OPEN ( "Open" ), + /** Save menu item */ + SAVE ( "Save" ), + /** Save as menu item */ + SAVE_AS ( "Save As...", 'a' ), + /** View warning log menu item */ + VIEW_WARNING_LOG( "View Warning Log" ), + /** Exit menu item */ + EXIT ( "Exit", 'x' ), + /** KeyStore menu */ + KEY_STORE ( true, "KeyStore" ), + /** Edit menu item */ + EDIT ( "Edit" ); + /** If true, then this represents a menu instead of a menu item. */ public final boolean isMenu; /** Text of the menu item. */ @@ -102,7 +118,7 @@ public final String text; /** Mnemonic for the menu item. */ public final char mnemonic; - + /** * Creates a new MenuItemEnum with a default mnemonic of the first character of its text. * @param isMenu indicating if this will be a menu @@ -111,7 +127,7 @@ private MenuItemEnum( final boolean isMenu, final String text ) { this( isMenu, text, text.charAt( 0 ) ); } - + /** * Creates a new MenuItemEnum with a default mnemonic of the first character of its text. * @param text text of the menu item @@ -119,7 +135,7 @@ private MenuItemEnum( final String text ) { this( false, text, text.charAt( 0 ) ); } - + /** * Creates a new MenuItemEnum. * @param text text of the menu item @@ -128,7 +144,7 @@ private MenuItemEnum( final String text, final char mnemonic ) { this( false, text, mnemonic ); } - + /** * Creates a new MenuItemEnum. * @param isMenu indicating if this will be a menu @@ -140,9 +156,9 @@ this.text = text; this.mnemonic = mnemonic; } - + }; - + /** * Builds the menus and the menu bar. * @param controller reference to the controller @@ -149,7 +165,7 @@ */ private void buildMenusAndMenuBar( final Controller controller ) { final JMenuBar menuBar = new JMenuBar(); - + JMenu menu = null; for ( final MenuItemEnum menuItemEnum : MenuItemEnum.values() ) { if ( menuItemEnum.isMenu ) { @@ -156,7 +172,8 @@ menu = new JMenu( menuItemEnum.text ); menu.setMnemonic( menuItemEnum.mnemonic ); menuBar.add( menu ); - } else { + } + else { final JMenuItem menuItem = new JMenuItem( menuItemEnum.text ); menuItem.setMnemonic( menuItemEnum.mnemonic ); menuItem.addActionListener( controller ); @@ -166,10 +183,10 @@ controller.setKeystoreEditMenuItem( menuItem ); } } - + setJMenuBar( menuBar ); } - + /** * Builds the tabbed pane containing the editor panels. * @param controller reference to the controller @@ -177,20 +194,33 @@ private void buildTabbedPane( final Controller controller ) { final JTabbedPane tabbedPane = new JTabbedPane(); final EditorPanel[] editorPanels = controller.getEditorPanels(); - + for ( int i = 0; i < editorPanels.length; i++ ) { final EditorPanel editorPanel = editorPanels[ i ]; final String panelTitle = (i+1) + " " + editorPanel.getPanelTitle(); - + tabbedPane.addTab( panelTitle, editorPanel ); - + if ( i < 9 ) // We only set 1..9 mnemonic characters tabbedPane.setMnemonicAt( i, '1' + i ); } - + tabbedPane.addChangeListener( controller ); - + add( tabbedPane , BorderLayout.CENTER ); } - + + /** + * Sets the displayed policy file. + * @param displayedPolicyFile displayed policy file to be set + */ + public void setDisplayedPolicyFile( final File displayedPolicyFile ) { + try { + policyFileDisplayerTextField.setText( displayedPolicyFile == null ? null : displayedPolicyFile.getCanonicalPath() ); + } catch ( final IOException ie ) { + // This should never happen... + ie.printStackTrace(); + } + } + } Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/EditorPanel.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/EditorPanel.java (revision 674165) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/EditorPanel.java (working copy) @@ -22,27 +22,37 @@ import javax.swing.JPanel; /** - * Defines an abstract editor panel which can provide a GUI for - * editing a policy text. + * Defines an abstract editor panel which can provide a GUI for editing a policy text. */ public abstract class EditorPanel extends JPanel { - + + /** Reference to the main frame. */ + protected final MainFrame mainFrame; + + /** The title of the panel. */ + protected String panelTitle; + /** Tells whether this editor panel has unsaved changes. */ - protected boolean hasDirty; + protected boolean hasDirty; /** Tells whether this editor panel supports graphical keystore edit. */ - protected boolean supportsGraphicalKeystoreEdit; - + protected boolean supportsGraphicalKeystoreEdit; + /** * Creates a new EditorPanel.
* Awaits a layout manager to be sent to the super class. + * @param mainFrame reference to the main frame + * @param panelTitle the title of the panel * @param layoutManager layout manager to be used * @param supportsGraphicalKeystoreEdit true if this editor panel supports graphical keystore edit; false otherwise */ - public EditorPanel( final LayoutManager layoutManager, final boolean supportsGraphicalKeystoreEdit ) { + public EditorPanel( final MainFrame mainFrame, final String panelTitle, final LayoutManager layoutManager, final boolean supportsGraphicalKeystoreEdit ) { super( layoutManager ); + + this.mainFrame = mainFrame; + this.panelTitle = panelTitle; this.supportsGraphicalKeystoreEdit = supportsGraphicalKeystoreEdit; } - + /** * Returns the title of the panel. * @return the title of the panel @@ -47,14 +57,18 @@ * Returns the title of the panel. * @return the title of the panel */ - public abstract String getPanelTitle(); - + public String getPanelTitle() { + return panelTitle; + } + /** - * Loads the specified policy text into the editor panel. + * Loads the specified policy text into the editor panel.
+ * If loading fails, leaves the current policy text intact. * @param policyText policy text to be loaded + * @return true if loading was successful; false otherwise */ - public abstract void loadPolicyText( final String policyText ); - + public abstract boolean loadPolicyText( final String policyText ); + /** * Returns the policy text hold by this editor panel. * @return the policy text hold by this editor panel @@ -60,7 +74,7 @@ * @return the policy text hold by this editor panel */ public abstract String getPolicyText(); - + /** * Tells whether this editor panel has unsaved changes. * @return true if the editor panel has unsaved changes @@ -68,7 +82,7 @@ public boolean getHasDirty() { return hasDirty; } - + /** * Sets the hasDirty property. * @param hasDirty value of hasDirty to be set @@ -76,7 +90,7 @@ public void setHasDirty( final boolean hasDirty ) { this.hasDirty = hasDirty; } - + /** * Tells whether this editor panel supports graphical keystore edit. * @return true if this editor panel supports graphical keystore edit; false otherwise @@ -84,5 +98,5 @@ public boolean supportsGraphicalKeystoreEdit() { return supportsGraphicalKeystoreEdit; } - + } Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/KeystoreEntryEditFormDialog.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/KeystoreEntryEditFormDialog.java (revision 0) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/KeystoreEntryEditFormDialog.java (revision 0) @@ -0,0 +1,164 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.harmony.tools.policytool.view; + +import java.awt.BorderLayout; +import java.awt.Frame; +import java.awt.GridLayout; +import java.util.List; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; + +import org.apache.harmony.tools.policytool.model.CommentEntry; +import org.apache.harmony.tools.policytool.model.KeystoreEntry; +import org.apache.harmony.tools.policytool.model.KeystorePasswordURLEntry; +import org.apache.harmony.tools.policytool.model.PolicyEntry; + +/** + * Form dialog to view and edit the keystore and the keystore password url entries. + */ +public class KeystoreEntryEditFormDialog extends BaseFormDialog { + + /** Reference to the initial editable keystore entry. */ + private final KeystoreEntry initialKeystoreEntry; + /** Reference to the initial editable keystore password URL entry. */ + private final KeystorePasswordURLEntry initialKeystorePasswordURLEntry; + /** List of policy entries where to store if new entries are to be created. */ + private final List< PolicyEntry > policyEntryList; + + /** Text field to view and edit the value of keystore URL. */ + private final JTextField keystoreURLTextField = new JTextField( 10 ); + /** Text field to view and edit the value of keystore type. */ + private final JTextField keystoreTypeTextField = new JTextField( 10 ); + /** Text field to view and edit the value of keystore provider. */ + private final JTextField keystoreProviderTextField = new JTextField( 10 ); + /** Text field to view and edit the value of keystore password URL. */ + private final JTextField keystorePasswordURLTextField = new JTextField( 10 ); + + /** + * Creates a new KeystoreEntryEditFormDialog. + * @param ownerFrame reference to the owner frame + * @param ownerEditorPanel reference to the owner editor panel + * @param keystoreEntry reference to the editable keystore entry + * @param keystorePasswordURLEntry reference to the editable password URL entry + * @param policyEntryList list of policy entries where to store if new entries are to be created + */ + public KeystoreEntryEditFormDialog( final Frame ownerFrame, final EditorPanel ownerEditorPanel, final KeystoreEntry keystoreEntry, final KeystorePasswordURLEntry keystorePasswordURLEntry, final List< PolicyEntry > policyEntryList ) { + super( ownerFrame, "KeyStore", ownerEditorPanel ); + + this.initialKeystoreEntry = keystoreEntry; + this.initialKeystorePasswordURLEntry = keystorePasswordURLEntry; + this.policyEntryList = policyEntryList; + + buildGUI(); + pack(); + center(); + } + + /** + * Builds the GUI of the dialog. + */ + private void buildGUI() { + final JPanel panel = new JPanel( new GridLayout( 4, 2, 5, 10 ) ); + + panel.add( new JLabel( "KeyStore URL:" ) ); + panel.add( keystoreURLTextField ); + + panel.add( new JLabel( "KeyStore Type:" ) ); + panel.add( keystoreTypeTextField ); + + panel.add( new JLabel( "KeyStore Provider:" ) ); + panel.add( keystoreProviderTextField ); + + panel.add( new JLabel( "KeyStore Password URL:" ) ); + panel.add( keystorePasswordURLTextField ); + + if ( initialKeystoreEntry != null ) { + keystoreURLTextField .setText( initialKeystoreEntry.getUrl () ); + keystoreTypeTextField .setText( initialKeystoreEntry.getType () ); + keystoreProviderTextField.setText( initialKeystoreEntry.getProvider() ); + } + + if ( initialKeystorePasswordURLEntry != null ) { + keystorePasswordURLTextField.setText( initialKeystorePasswordURLEntry.getUrl() ); + } + + final JPanel flowPanel = new JPanel(); + flowPanel.add( panel ); + add( new JScrollPane( flowPanel ), BorderLayout.CENTER ); + } + + @Override + public void onOkButtonPressed() { + // TODO: validation + + final KeystoreEntry keystoreEntry = initialKeystoreEntry == null ? new KeystoreEntry() : initialKeystoreEntry; + + if ( keystoreURLTextField.getText().length() == 0 && keystoreTypeTextField.getText().length() == 0 && keystoreProviderTextField.getText().length() == 0 ) { + // We want no keystore entry! + if ( initialKeystoreEntry != null ) + policyEntryList.remove( initialKeystoreEntry ); + } + else { + keystoreEntry.setUrl ( keystoreURLTextField .getText() ); + keystoreEntry.setType ( keystoreTypeTextField .getText() ); + keystoreEntry.setProvider( keystoreProviderTextField.getText() ); + + if ( initialKeystoreEntry == null ) { // If it is a new, we have to add it to the "global" list + // We want to add it to be the first non-comment entry + int index = 0; + for ( ; index < policyEntryList.size(); index++ ) + if ( !( policyEntryList.get( index ) instanceof CommentEntry ) ) + break; + policyEntryList.add( index, keystoreEntry ); + } + } + + if ( keystorePasswordURLTextField.getText().length() == 0 ) { + // We want no keystore password URL entry! + if ( initialKeystorePasswordURLEntry != null ) + policyEntryList.remove( initialKeystorePasswordURLEntry ); + } + else { + final KeystorePasswordURLEntry keystorePasswordURLEntry = initialKeystorePasswordURLEntry == null ? new KeystorePasswordURLEntry() : initialKeystorePasswordURLEntry; + keystorePasswordURLEntry.setUrl( keystorePasswordURLTextField.getText() ); + + if ( initialKeystorePasswordURLEntry == null ) { // If it is a new, we have to add it to the "global" list + // We want to add it after the keystore entry + int index = policyEntryList.indexOf( keystoreEntry ); + if ( index < 0 ) { // No such entry exists, we want it to be the first non-comment entry then + index = 0; + for ( ; index < policyEntryList.size(); index++ ) + if ( !( policyEntryList.get( index ) instanceof CommentEntry ) ) + break; + } + else + index++; // => after the keystore entry (not before) + policyEntryList.add( index, keystorePasswordURLEntry ); + } + } + + ownerEditorPanel.setHasDirty( true ); + + dispose(); + } + +} Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/DirectTextEditorPanel.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/DirectTextEditorPanel.java (revision 674165) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/view/DirectTextEditorPanel.java (working copy) @@ -31,44 +31,41 @@ * An editor panel which provides an interface for direct editing the policy text. */ public class DirectTextEditorPanel extends EditorPanel { - + /** Text area for direct editing the policy text. */ private final JTextArea policyTextTextArea = new JTextArea(); - + /** * Creates a new DirectTextEditorPanel.
* Sets a BorderLayout as the layout manager. + * @param mainFrame reference to the main frame */ - public DirectTextEditorPanel() { - super( new BorderLayout(), false ); - + public DirectTextEditorPanel( final MainFrame mainFrame ) { + super( mainFrame, "Direct editing", new BorderLayout(), false ); + policyTextTextArea.setFont( new Font( "Courier New", Font.PLAIN, Consts.DIRECT_EDITING_FONT_SIZE ) ); - + // We want to track changes of the document so we can ask confirmation on exit policyTextTextArea.getDocument().addDocumentListener( new DocumentListener() { - public void changedUpdate( final DocumentEvent de ) { - } - public void insertUpdate ( final DocumentEvent de ) { - setHasDirty( true ); - } - public void removeUpdate ( final DocumentEvent de ) { - setHasDirty( true ); - } - } ); - + public void changedUpdate( final DocumentEvent de ) { + } + public void insertUpdate ( final DocumentEvent de ) { + setHasDirty( true ); + } + public void removeUpdate ( final DocumentEvent de ) { + setHasDirty( true ); + } + } ); + add( new JScrollPane( policyTextTextArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS ), BorderLayout.CENTER ); } - + @Override - public String getPanelTitle() { - return "Direct editing"; - } - - @Override - public void loadPolicyText( final String policyText ) { + public boolean loadPolicyText( final String policyText ) { policyTextTextArea.setText( policyText ); + return true; } - + @Override public String getPolicyText() { return policyTextTextArea.getText(); @@ -73,5 +70,5 @@ public String getPolicyText() { return policyTextTextArea.getText(); } - + } Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/Consts.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/Consts.java (revision 674165) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/Consts.java (working copy) @@ -21,10 +21,10 @@ * Holds general and application-wide constants. */ public class Consts { - + /** Name of the application. */ public static final String APPLICATION_NAME = "Policytool"; - + /** X coordinate of the main frame on startup. */ public static final int MAIN_FRAME_START_POS_X = 200; /** Y coordinate of the main frame on startup. */ @@ -29,8 +29,8 @@ public static final int MAIN_FRAME_START_POS_X = 200; /** Y coordinate of the main frame on startup. */ public static final int MAIN_FRAME_START_POS_Y = 100; - + /** Font size in the direct editing panel. */ public static final int DIRECT_EDITING_FONT_SIZE = 13; - + } Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/control/Controller.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/control/Controller.java (revision 674165) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/control/Controller.java (working copy) @@ -17,7 +17,6 @@ package org.apache.harmony.tools.policytool.control; -import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; @@ -30,16 +29,17 @@ import javax.swing.event.ChangeListener; import org.apache.harmony.tools.policytool.view.EditorPanel; +import org.apache.harmony.tools.policytool.view.GraphicalEditorPanel; +import org.apache.harmony.tools.policytool.view.MainFrame; import org.apache.harmony.tools.policytool.view.MainFrame.MenuItemEnum; /** - * The controller handles the user actions, drives the GUI and - * connects it to the model. + * The controller handles the user actions, drives the GUI and connects it to the model. */ public class Controller implements ChangeListener, ActionListener{ - - /** Reference to the main frame component. */ - private final Component mainFrame; + + /** Reference to the main frame. */ + private final MainFrame mainFrame; /** Array of the editor panels. */ private final EditorPanel[] editorPanels; /** Reference to the active editor panel. */ @@ -44,30 +44,33 @@ private final EditorPanel[] editorPanels; /** Reference to the active editor panel. */ private EditorPanel activeEditorPanel; - + /** Reference to the keystore edit menu item. */ private JMenuItem keystoreEditMenuItem; - + /** The currently edited policy file. */ - private File editedPolicyFile; - + private File editedPolicyFile; + /** * Creates a new Controller. - * @param mainFrame reference to the main frame component + * @param mainFrame reference to the main frame * @param editorPanels array of the editor panels * @param policyFileName policy file name to be loaded initially */ - public Controller( final Component mainFrame, final EditorPanel[] editorPanels, final String policyFileName ) { + public Controller( final MainFrame mainFrame, final EditorPanel[] editorPanels, final String policyFileName ) { this.mainFrame = mainFrame; this.editorPanels = editorPanels; activeEditorPanel = editorPanels[ 0 ]; - + PolicyFileHandler.setDialogParentComponent( mainFrame ); - - editedPolicyFile = new File( policyFileName ); - activeEditorPanel.loadPolicyText( PolicyFileHandler.loadPoilcyFile( editedPolicyFile ) ); + + if ( policyFileName != null ) { + final File editedPolicyFile_ = new File( policyFileName ); + if ( activeEditorPanel.loadPolicyText( PolicyFileHandler.loadPolicyFile( editedPolicyFile_ ) ) ) + setEditedPolicyFile( editedPolicyFile_ ); + } } - + /** * Returns the array of editor panels. * @return the array of editor panels @@ -75,7 +78,7 @@ public EditorPanel[] getEditorPanels() { return editorPanels; } - + /** * Sets the keystore edit menu item. * @param keystoreEditMenuItem the keystore edit menu item @@ -84,7 +87,7 @@ this.keystoreEditMenuItem = keystoreEditMenuItem; keystoreEditMenuItem.setEnabled( activeEditorPanel.supportsGraphicalKeystoreEdit() ); } - + /** * Exits from the program.
* There might be unsaved changes in which case confirmation will be asked. @@ -90,15 +93,30 @@ * There might be unsaved changes in which case confirmation will be asked. */ public void exit() { - boolean exitOk = false; - + if ( allowedDirtySensitiveOperation( "exit" ) ) + System.exit( 0 ); + } + + /** + * Determines if a dirty sensitive operation is allowed to be executed.
+ * There are operation which will throw away the edited policy text currently hold in the active editor + * (for example exit or load a file, or start a new).
+ * This method checks whether there are unsaved changes, and if so, ask confirmation on what to do with them.
+ * Finally returns true, if the dirty data can be thrown away or has been saved successfully. + * Returns false, if the effect of the operation (throwing away unsaved changes) is unwanted and therefore the operation is disallowed. + * + * @param operationName name of the operation which will be included in the confirmation messages + * @return true, if the operation now can be performed safely; false otherwise + */ + private boolean allowedDirtySensitiveOperation( final String operationName ) { if ( activeEditorPanel.getHasDirty() ) { - - switch ( JOptionPane.showConfirmDialog( mainFrame, "There are unsaved changes. Save before exit?", "Warning", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE ) ) { - + + switch ( JOptionPane.showConfirmDialog( mainFrame, "There are unsaved changes. Save before " + operationName + "?", "Warning", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE ) ) { + case JOptionPane.YES_OPTION: + // We chose to save file first final JFileChooser fileChooser = new JFileChooser(); - + if ( editedPolicyFile == null ) { if ( fileChooser.showSaveDialog( mainFrame ) == JFileChooser.APPROVE_OPTION ) editedPolicyFile = fileChooser.getSelectedFile(); @@ -105,41 +123,41 @@ } if ( editedPolicyFile != null ) { if ( !PolicyFileHandler.savePolicyFile( editedPolicyFile, activeEditorPanel.getPolicyText() ) ) { - switch ( JOptionPane.showConfirmDialog( mainFrame, "Saving failed. Do you still want to exit?", "Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE ) ) { + switch ( JOptionPane.showConfirmDialog( mainFrame, "Saving failed. Do you still want to " + operationName + "?", "Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE ) ) { case JOptionPane.YES_OPTION: - exitOk = true; - break; - + // We chose to still proceed + return true; + case JOptionPane.NO_OPTION: case JOptionPane.CLOSED_OPTION: - // We chose not to exit. exitOk = false - break; + // We chose not to proceed + return false; } - } else {// Changes saved successfully + } + else {// Changes saved successfully activeEditorPanel.setHasDirty( false ); - exitOk = true; + mainFrame.setDisplayedPolicyFile( editedPolicyFile ); + return true; } } break; - + case JOptionPane.NO_OPTION: - exitOk = true; - break; - + // We chose not to save and proceed + return true; + case JOptionPane.CANCEL_OPTION: case JOptionPane.CLOSED_OPTION: - // We chose not to exit. exitOk = false - break; - + // We chose not to proceed + return false; + } - - } else - exitOk = true; - - if ( exitOk ) - System.exit( 0 ); + + } + + return true; } - + /** * Handles change events of the editors tabbed pane. * @param ce details of the change event @@ -146,14 +164,14 @@ */ public void stateChanged( final ChangeEvent ce ) { final EditorPanel newActiveEditorPanel = (EditorPanel) ( (JTabbedPane) ce.getSource() ).getSelectedComponent(); - + newActiveEditorPanel.loadPolicyText( activeEditorPanel.getPolicyText() ); newActiveEditorPanel.setHasDirty ( activeEditorPanel.getHasDirty () ); activeEditorPanel = newActiveEditorPanel; - + keystoreEditMenuItem.setEnabled( activeEditorPanel.supportsGraphicalKeystoreEdit() ); } - + /** * Handles the action events of the menu items. * @param ae details of the action event @@ -161,50 +179,73 @@ public void actionPerformed( final ActionEvent ae ) { // The action command is the ordinal of the menu item enum. final MenuItemEnum menuItemEnum = MenuItemEnum.values()[ Integer.parseInt( ae.getActionCommand() ) ]; - + + File editedPolicyFile_ = null; + final JFileChooser fileChooser = new JFileChooser(); switch ( menuItemEnum ) { - + case NEW : + if ( allowedDirtySensitiveOperation( "starting new file" ) ) { + activeEditorPanel.loadPolicyText( null ); + setEditedPolicyFile( null ); + } break; - + case OPEN : - if ( fileChooser.showOpenDialog( mainFrame ) == JFileChooser.APPROVE_OPTION ) { - editedPolicyFile = fileChooser.getSelectedFile(); - activeEditorPanel.loadPolicyText( PolicyFileHandler.loadPoilcyFile( editedPolicyFile ) ); - } + if ( allowedDirtySensitiveOperation( "opening file" ) ) + if ( fileChooser.showOpenDialog( mainFrame ) == JFileChooser.APPROVE_OPTION ) { + editedPolicyFile_ = fileChooser.getSelectedFile(); + if ( activeEditorPanel.loadPolicyText( PolicyFileHandler.loadPolicyFile( editedPolicyFile_ ) ) ) + setEditedPolicyFile( editedPolicyFile_ ); + } break; - + case SAVE : if ( editedPolicyFile == null ) { if ( fileChooser.showSaveDialog( mainFrame ) == JFileChooser.APPROVE_OPTION ) - editedPolicyFile = fileChooser.getSelectedFile(); + editedPolicyFile_ = fileChooser.getSelectedFile(); } - if ( editedPolicyFile != null ) - if ( PolicyFileHandler.savePolicyFile( editedPolicyFile, activeEditorPanel.getPolicyText() ) ) - activeEditorPanel.setHasDirty( false ); + else + editedPolicyFile_ = editedPolicyFile; + + if ( editedPolicyFile_ != null ) + if ( PolicyFileHandler.savePolicyFile( editedPolicyFile_, activeEditorPanel.getPolicyText() ) ) + setEditedPolicyFile( editedPolicyFile_ ); break; - + case SAVE_AS : if ( fileChooser.showSaveDialog( mainFrame ) == JFileChooser.APPROVE_OPTION ) { - editedPolicyFile = fileChooser.getSelectedFile(); - if ( PolicyFileHandler.savePolicyFile( editedPolicyFile, activeEditorPanel.getPolicyText() ) ) - activeEditorPanel.setHasDirty( false ); + editedPolicyFile_ = fileChooser.getSelectedFile(); + if ( PolicyFileHandler.savePolicyFile( editedPolicyFile_, activeEditorPanel.getPolicyText() ) ) + setEditedPolicyFile( editedPolicyFile_ ); } break; - + case VIEW_WARNING_LOG : break; - + case EXIT : exit(); break; - + case EDIT : + if ( activeEditorPanel instanceof GraphicalEditorPanel ) + ( (GraphicalEditorPanel) activeEditorPanel ).showKeystoreEntryEditDialog(); break; - + } - + + } + + /** + * Sets the edited policy file and displays its name in the main frame. Also clears the dirty flag. + * @param editedPolicyFile edited policy file to be set + */ + private void setEditedPolicyFile( final File editedPolicyFile ) { + activeEditorPanel.setHasDirty( false ); + this.editedPolicyFile = editedPolicyFile; + mainFrame.setDisplayedPolicyFile( editedPolicyFile ); } - + } Index: modules/tools/src/main/java/org/apache/harmony/tools/policytool/control/PolicyFileHandler.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/policytool/control/PolicyFileHandler.java (revision 674165) +++ modules/tools/src/main/java/org/apache/harmony/tools/policytool/control/PolicyFileHandler.java (working copy) @@ -35,16 +35,16 @@ * We're aware of the UTF-8 policy file encoding. */ public class PolicyFileHandler { - + /** Encoding of the policy file by the specification. */ private static final String POLICY_FILE_ENCODING = "UTF-8"; - + /** Platform dependent line separator. */ private static final String LINE_SEPARATOR = System.getProperty( "line.separator" ); - + /** Parent component to be used when displaying dialogs. */ private static Component dialogParentComponent; - + /** * Sets the parent component to be used when displaying dialogs. * @param dialogParentComponent component to be used when displaying dialogs @@ -52,7 +52,7 @@ public static void setDialogParentComponent( final Component dialogParentComponent ) { PolicyFileHandler.dialogParentComponent = dialogParentComponent; } - + /** * Loads the content of a policy file. * @param policyFile policy file whose content to be loaded @@ -58,12 +58,12 @@ * @param policyFile policy file whose content to be loaded * @return the policy text within the given policy file */ - public static String loadPoilcyFile( final File policyFile ) { + public static String loadPolicyFile( final File policyFile ) { final StringBuilder policyTextBuilder = new StringBuilder(); - + BufferedReader input = null; try { - + input = new BufferedReader( new InputStreamReader( new FileInputStream( policyFile ), POLICY_FILE_ENCODING ) ); String line; while ( ( line = input.readLine() ) != null ) @@ -68,28 +68,34 @@ String line; while ( ( line = input.readLine() ) != null ) policyTextBuilder.append( line ).append( LINE_SEPARATOR ); - } catch ( final FileNotFoundException fnfe ) { + + } + catch ( final FileNotFoundException fnfe ) { JOptionPane.showMessageDialog( dialogParentComponent, "The file does not exist!", "Error", JOptionPane.ERROR_MESSAGE ); return null; - } catch ( final UnsupportedEncodingException uee ) { + } + catch ( final UnsupportedEncodingException uee ) { // This should never happen. uee.printStackTrace(); return null; - } catch ( final IOException ie ) { + } + catch ( final IOException ie ) { JOptionPane.showMessageDialog( dialogParentComponent, new String[] { "I/O error occured, can't read the file!", ie.getMessage() }, "Error", JOptionPane.ERROR_MESSAGE ); return null; - } finally { + } + finally { if ( input != null ) try { input.close(); - } catch ( final IOException ie ) { + } + catch ( final IOException ie ) { ie.printStackTrace(); } } - + return policyTextBuilder.toString(); } - + /** * Saves policy text to a policy file. * @param policyFile policy file to save to @@ -100,14 +106,16 @@ OutputStreamWriter output = null; try { output = new OutputStreamWriter( new FileOutputStream( policyFile ), POLICY_FILE_ENCODING ); - + output.write( policyText ); - + return true; - } catch ( final UnsupportedEncodingException uee ) { + } + catch ( final UnsupportedEncodingException uee ) { // This should never happen. uee.printStackTrace(); - } catch ( final FileNotFoundException ffe ) { + } + catch ( final FileNotFoundException ffe ) { JOptionPane.showMessageDialog( dialogParentComponent, new String[] { "Cannot open file for writing!", ffe.getMessage() }, "Error", JOptionPane.ERROR_MESSAGE ); ffe.printStackTrace(); } catch ( final IOException ie ) { @@ -113,16 +121,18 @@ } catch ( final IOException ie ) { JOptionPane.showMessageDialog( dialogParentComponent, new String[] { "Write error!", ie.getMessage() }, "Error", JOptionPane.ERROR_MESSAGE ); ie.printStackTrace(); - } finally { + } + finally { if ( output != null ) try { output.close(); - } catch ( final IOException ie ) { + } + catch ( final IOException ie ) { ie.printStackTrace(); } } - + return false; } - + }