Explorar o código

Initial commit: AdminTool

Mathias Landhäußer %!s(int64=11) %!d(string=hai) anos
pai
achega
751031b3bd

+ 181 - 0
jplag.adminTool/pom.xml

@@ -0,0 +1,181 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>adminTool</artifactId>
+	<version>1.0.317-SNAPSHOT</version>
+
+	<parent>
+		<groupId>edu.kit.ipd.jplag</groupId>
+		<artifactId>parent</artifactId>
+		<version>0.3-SNAPSHOT</version>
+	</parent>
+
+	<repositories>
+		<repository>
+			<id>ipdNexus</id>
+			<name>Recaa Repository</name>
+			<url>http://bob.ipd.kit.edu/nexus/content/repositories/public/</url>
+		</repository>
+		<repository>
+			<id>projectLocal</id>
+			<name>Local Repository</name>
+			<url>file://${project.basedir}/../../maven-libs</url>
+		</repository>
+	</repositories>
+
+	<properties>
+		<!-- Properties for keystore generation -->
+		<webstart.keystore>overwrite_in_settings.xml</webstart.keystore>
+		<webstart.keypass>overwrite_in_settings.xml</webstart.keypass>
+		<webstart.storepass>overwrite_in_settins.xml</webstart.storepass>
+		<webstart.alias>jplag</webstart.alias>
+		<webstart.keystore.delete>false</webstart.keystore.delete>
+		<webstart.keystore.gen>false</webstart.keystore.gen>
+		<jnlpIcon64x64>admintool.icon.ico</jnlpIcon64x64>
+		<jnlpSplash>admintool.splash.gif</jnlpSplash>
+	</properties>
+
+	<build>
+		<resources>
+			<resource>
+				<directory>src/main/resources</directory>
+				<filtering>true</filtering>
+				<includes>
+					<include>jplagAdminTool/version.properties</include>
+				</includes>
+			</resource>
+			<resource>
+				<directory>src/main/resources</directory>
+				<filtering>false</filtering>
+				<excludes>
+					<exclude>jplagAdminTool/version.properties</exclude>
+				</excludes>
+			</resource>
+		</resources>
+
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-jar-plugin</artifactId>
+				<configuration>
+					<archive>
+						<manifest>
+							<mainClass>jplagAdminTool.AdminTool</mainClass>
+							<packageName>jplagAdminTool</packageName>
+						</manifest>
+					</archive>
+				</configuration>
+			</plugin>
+
+			<plugin>
+				<artifactId>maven-assembly-plugin</artifactId>
+				<version>2.4</version>
+				<configuration>
+					<descriptorRefs>
+						<descriptorRef>jar-with-dependencies</descriptorRef>
+					</descriptorRefs>
+
+					<archive>
+						<manifest>
+							<mainClass>jplagAdminTool.AdminTool</mainClass>
+							<packageName>jplagAdminTool</packageName>
+						</manifest>
+					</archive>
+				</configuration>
+			</plugin>
+
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>webstart-maven-plugin</artifactId>
+				<version>1.0-beta-6</version>
+				<executions>
+					<execution>
+						<phase>process-resources</phase>
+						<goals>
+							<goal>jnlp</goal>
+						</goals>
+					</execution>
+				</executions>
+
+				<!-- http://mojo.codehaus.org/webstart/webstart-maven-plugin/jnlp-mojos-overview.html -->
+				<configuration>
+					<verbose>true</verbose>
+					<jnlp>
+						<mainClass>jplagAdminTool.AdminTool</mainClass>
+					</jnlp>
+					<codebase>https://jplag.ipd.kit.edu/admintool</codebase>
+					<j2seVersion>${project.build.target}+</j2seVersion>
+
+					<updateManifestEntries>
+						<Permissions>all-permissions</Permissions>
+						<Codebase>*</Codebase>
+					</updateManifestEntries>
+
+					<!-- SIGNING -->
+					<!-- defining this will automatically sign the jar and its dependencies, 
+						if necessary -->
+					<sign>
+						<keystore>${webstart.keystore}</keystore>
+						<storetype>${webstart.storetype}</storetype>
+						<keypass>${webstart.keypass}</keypass> <!-- we need to override passwords easily from the command line. ${keypass} -->
+						<storepass>${webstart.storepass}</storepass> <!-- ${storepass} -->
+						<alias>${webstart.alias}</alias>
+
+						<validity>1095</validity>
+
+						<!-- only required for generating the keystore -->
+						<dnameCn>jplag.ipd.kit.edu</dnameCn>
+						<dnameOu>IPD Tichy</dnameOu>
+						<dnameO>Karlsruhe Institute of Technology</dnameO>
+						<dnameL>Karlsruhe</dnameL>
+						<dnameSt>Baden-Wuerttemberg</dnameSt>
+						<dnameC>Germany</dnameC>
+
+						<!-- verify that the signing operation succeeded -->
+						<verify>true</verify>
+
+						<!-- KEYSTORE MANAGEMENT -->
+						<keystoreConfig>
+							<delete>${webstart.keystore.delete}</delete> <!-- delete the keystore -->
+							<gen>${webstart.keystore.generate}</gen>       <!-- optional shortcut to generate the store. -->
+						</keystoreConfig>
+					</sign>
+				</configuration>
+			</plugin>
+
+		</plugins>
+	</build>
+
+	<dependencies>
+		<dependency>
+			<groupId>com.sun</groupId>
+			<artifactId>javaws</artifactId>
+			<version>1.7.0_40</version>
+			<optional>true</optional>
+			<scope>provided</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>javax.xml</groupId>
+			<artifactId>jaxrpc-api</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.sun.xml.rpc</groupId>
+			<artifactId>jaxrpc-impl</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>edu.kit.ipd.jplag</groupId>
+			<artifactId>wsClient</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>edu.kit.ipd.jplag</groupId>
+			<artifactId>utils</artifactId>
+		</dependency>
+	</dependencies>
+
+	<description>Tool to change, add or delete user accounts  for the JPlag WebService.</description>
+	<name>JPlag AdminTool</name>
+	<url>http://www.jplag.de</url>
+</project>

+ 564 - 0
jplag.adminTool/src/main/java/jplagAdminTool/AddUserDialog.java

@@ -0,0 +1,564 @@
+package jplagAdminTool;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.text.ParseException;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JRootPane;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.KeyStroke;
+
+import jplagWsClient.jplagClient.SetUserDataParams;
+
+public class AddUserDialog extends JDialog {
+
+	private static final long serialVersionUID = 7452010241285343412L;
+	private javax.swing.JPanel jContentPane = null;
+	private JPanel jPanel = null;
+	private JLabel jLabel = null;
+	private JTextField jUsernameField = null;
+	private JLabel jLabel1 = null;
+	private JTextField jPasswordField = null;
+	private JLabel jLabel2 = null;
+	private JTextField jRealnameField = null;
+	private JLabel jLabel3 = null;
+	private JTextField jEmailField = null;
+	private JLabel jLabel4 = null;
+	private JTextField jEmailSecondField = null;
+	private JLabel jLabel5 = null;
+	private JTextField jHomepageField = null;
+	private JLabel jLabel6 = null;
+	private JTextArea jNotesTextArea = null;
+	private JLabel jLabel7 = null;
+	private JComboBox<String> jStateComboBox = null;
+	private JPanel jPanel1 = null;
+	private JButton jOKButton = null;
+	private JButton jCancelButton = null;
+	
+	private AdminTool adminTool = null;
+	private JLabel jLabel8 = null;
+	private JTextField jExpiresField = null;
+	private JScrollPane jScrollPane = null;
+	private JLabel jLabel9 = null;
+	private JScrollPane jScrollPane1 = null;
+	private JTextArea jReasonTextArea = null;
+	/**
+	 * This is the default constructor
+	 */
+	public AddUserDialog(AdminTool adTool) {
+		super(adTool,true);
+		adminTool=adTool;
+		initialize();
+	}
+
+	protected JRootPane createRootPane() {
+		KeyStroke stroke=KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
+		JRootPane rootPane=new JRootPane();
+		rootPane.registerKeyboardAction(new ActionListener() {
+				public void actionPerformed(ActionEvent actionEvent) {
+					setVisible(false);
+				}
+			}, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
+		
+		return rootPane;
+	}
+	
+	/**
+	 * This method initializes this
+	 * 
+	 * @return void
+	 */
+	private void initialize() {
+		this.setSize(396, 325);
+		this.setTitle("Add a new user...");
+		this.setContentPane(getJContentPane());
+	}
+
+	/**
+	 * This method initializes jContentPane
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	private javax.swing.JPanel getJContentPane() {
+		if(jContentPane == null) {
+			jContentPane = new javax.swing.JPanel();
+			jContentPane.setLayout(new java.awt.BorderLayout());
+			jContentPane.add(getJPanel1(), java.awt.BorderLayout.SOUTH);
+			jContentPane.add(getJPanel(), java.awt.BorderLayout.CENTER);
+		}
+		return jContentPane;
+	}
+
+	/**
+	 * This method initializes jPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */    
+	private JPanel getJPanel() {
+		if (jPanel == null) {
+			GridBagConstraints gridBagConstraints23 = new GridBagConstraints();
+			gridBagConstraints23.fill = java.awt.GridBagConstraints.BOTH;
+			gridBagConstraints23.gridx = 1;
+			gridBagConstraints23.gridy = 6;
+			gridBagConstraints23.weightx = 1.0;
+			gridBagConstraints23.weighty = 1.0;
+			GridBagConstraints gridBagConstraints19 = new GridBagConstraints();
+			gridBagConstraints19.gridx = 0;
+			gridBagConstraints19.gridy = 6;
+			gridBagConstraints19.anchor = java.awt.GridBagConstraints.NORTHWEST;
+			jLabel9 = new JLabel();
+			jLabel9.setText("Reason:");
+			GridBagConstraints gridBagConstraints111 = new GridBagConstraints();
+			gridBagConstraints111.fill = java.awt.GridBagConstraints.BOTH;
+			gridBagConstraints111.gridx = 1;
+			gridBagConstraints111.gridy = 7;
+			gridBagConstraints111.weightx = 1.0;
+			gridBagConstraints111.weighty = 1.0;
+			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
+			gridBagConstraints2.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints2.gridx = 1;
+			gridBagConstraints2.gridy = 9;
+			gridBagConstraints2.weightx = 1.0;
+			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
+			gridBagConstraints1.gridx = 0;
+			gridBagConstraints1.gridy = 9;
+			gridBagConstraints1.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel8 = new JLabel();
+			jLabel8.setText("Expires:");
+			GridBagConstraints gridBagConstraints22 = new GridBagConstraints();
+			gridBagConstraints22.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints22.gridx = 1;
+			gridBagConstraints22.gridy = 8;
+			gridBagConstraints22.weightx = 1.0;
+			GridBagConstraints gridBagConstraints21 = new GridBagConstraints();
+			gridBagConstraints21.gridx = 0;
+			gridBagConstraints21.gridy = 8;
+			gridBagConstraints21.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel7 = new JLabel();
+			jLabel7.setText("State:");
+			GridBagConstraints gridBagConstraints18 = new GridBagConstraints();
+			gridBagConstraints18.gridx = 0;
+			gridBagConstraints18.gridy = 7;
+			gridBagConstraints18.anchor = java.awt.GridBagConstraints.NORTHWEST;
+			jLabel6 = new JLabel();
+			jLabel6.setText("Notes:");
+			GridBagConstraints gridBagConstraints17 = new GridBagConstraints();
+			gridBagConstraints17.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints17.gridx = 1;
+			gridBagConstraints17.gridy = 5;
+			gridBagConstraints17.weightx = 1.0;
+			GridBagConstraints gridBagConstraints16 = new GridBagConstraints();
+			gridBagConstraints16.gridx = 0;
+			gridBagConstraints16.gridy = 5;
+			gridBagConstraints16.anchor = java.awt.GridBagConstraints.WEST;
+			gridBagConstraints16.insets = new java.awt.Insets(0,0,0,5);
+			jLabel5 = new JLabel();
+			jLabel5.setText("Homepage:");
+			GridBagConstraints gridBagConstraints15 = new GridBagConstraints();
+			gridBagConstraints15.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints15.gridx = 1;
+			gridBagConstraints15.gridy = 4;
+			gridBagConstraints15.weightx = 1.0;
+			GridBagConstraints gridBagConstraints14 = new GridBagConstraints();
+			gridBagConstraints14.gridx = 0;
+			gridBagConstraints14.gridy = 4;
+			gridBagConstraints14.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel4 = new JLabel();
+			jLabel4.setText("2. Email:");
+			GridBagConstraints gridBagConstraints13 = new GridBagConstraints();
+			gridBagConstraints13.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints13.gridx = 1;
+			gridBagConstraints13.gridy = 3;
+			gridBagConstraints13.weightx = 1.0;
+			GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
+			gridBagConstraints12.gridx = 0;
+			gridBagConstraints12.gridy = 3;
+			gridBagConstraints12.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel3 = new JLabel();
+			jLabel3.setText("Email:");
+			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
+			gridBagConstraints11.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints11.gridx = 1;
+			gridBagConstraints11.gridy = 2;
+			gridBagConstraints11.weightx = 1.0;
+			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
+			gridBagConstraints10.gridx = 0;
+			gridBagConstraints10.gridy = 2;
+			gridBagConstraints10.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel2 = new JLabel();
+			jLabel2.setText("Realname:");
+			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
+			gridBagConstraints9.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints9.gridx = 1;
+			gridBagConstraints9.gridy = 1;
+			gridBagConstraints9.weightx = 1.0;
+			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
+			gridBagConstraints8.gridx = 0;
+			gridBagConstraints8.gridy = 1;
+			gridBagConstraints8.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel1 = new JLabel();
+			jLabel1.setText("Password:");
+			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
+			gridBagConstraints7.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints7.gridx = 1;
+			gridBagConstraints7.gridy = 0;
+			gridBagConstraints7.weightx = 1.0;
+			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
+			gridBagConstraints6.gridx = 0;
+			gridBagConstraints6.gridy = 0;
+			gridBagConstraints6.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel = new JLabel();
+			jLabel.setText("Username:");
+			jPanel = new JPanel();
+			jPanel.setLayout(new GridBagLayout());
+			jPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(5,5,5,5));
+			jPanel.add(getJScrollPane1(), gridBagConstraints23);
+			jPanel.add(jLabel9, gridBagConstraints19);
+			jPanel.add(getJScrollPane(), gridBagConstraints111);
+			jPanel.add(jLabel, gridBagConstraints6);
+			jPanel.add(getJHomepageField(), gridBagConstraints17);
+			jPanel.add(getJEmailSecondField(), gridBagConstraints15);
+			jPanel.add(getJEmailField(), gridBagConstraints13);
+			jPanel.add(getJRealnameField(), gridBagConstraints11);
+			jPanel.add(getJPasswordField(), gridBagConstraints9);
+			jPanel.add(getJUsernameField(), gridBagConstraints7);
+			jPanel.add(jLabel1, gridBagConstraints8);
+			jPanel.add(jLabel2, gridBagConstraints10);
+			jPanel.add(jLabel3, gridBagConstraints12);
+			jPanel.add(jLabel4, gridBagConstraints14);
+			jPanel.add(jLabel5, gridBagConstraints16);
+			jPanel.add(jLabel6, gridBagConstraints18);
+			jPanel.add(jLabel7, gridBagConstraints21);
+			jPanel.add(getJStateComboBox(), gridBagConstraints22);
+			jPanel.add(jLabel8, gridBagConstraints1);
+			jPanel.add(getJExpiresField(), gridBagConstraints2);
+		}
+		return jPanel;
+	}
+
+	/**
+	 * This method initializes jTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJUsernameField() {
+		if (jUsernameField == null) {
+			jUsernameField = new JTextField();
+			jUsernameField.setPreferredSize(new java.awt.Dimension(300,20));
+		}
+		return jUsernameField;
+	}
+
+	/**
+	 * This method initializes jTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJPasswordField() {
+		if (jPasswordField == null) {
+			jPasswordField = new JTextField();
+		}
+		return jPasswordField;
+	}
+
+	/**
+	 * This method initializes jTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJRealnameField() {
+		if (jRealnameField == null) {
+			jRealnameField = new JTextField();
+		}
+		return jRealnameField;
+	}
+
+	/**
+	 * This method initializes jTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJEmailField() {
+		if (jEmailField == null) {
+			jEmailField = new JTextField();
+		}
+		return jEmailField;
+	}
+
+	/**
+	 * This method initializes jTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJEmailSecondField() {
+		if (jEmailSecondField == null) {
+			jEmailSecondField = new JTextField();
+		}
+		return jEmailSecondField;
+	}
+
+	/**
+	 * This method initializes jTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJHomepageField() {
+		if (jHomepageField == null) {
+			jHomepageField = new JTextField();
+		}
+		return jHomepageField;
+	}
+
+	/**
+	 * This method initializes jTextArea	
+	 * 	
+	 * @return javax.swing.JTextArea	
+	 */    
+	private JTextArea getJNotesTextArea() {
+		if (jNotesTextArea == null) {
+			jNotesTextArea = new JTextArea();
+			jNotesTextArea.setRows(3);
+			jNotesTextArea.setLineWrap(true);
+			jNotesTextArea.setWrapStyleWord(true);
+		}
+		return jNotesTextArea;
+	}
+
+	/**
+	 * This method initializes jTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJExpiresField() {
+		if (jExpiresField == null) {
+			jExpiresField = new JTextField();
+			GregorianCalendar c=new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+			c.add(Calendar.YEAR,1);
+			jExpiresField.setText(RequestDialog.formatCalendar(c));
+		}
+		return jExpiresField;
+	}
+	
+	/**
+	 * This method initializes jComboBox	
+	 * 	
+	 * @return javax.swing.JComboBox	
+	 */    
+	private JComboBox<String> getJStateComboBox() {
+		if (jStateComboBox == null) {
+			jStateComboBox = new JComboBox<String>(
+					BackedUserData.getStateNameArray(adminTool.getUserState()));
+		}
+		return jStateComboBox;
+	}
+
+	/**
+	 * This method initializes jPanel1	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */    
+	private JPanel getJPanel1() {
+		if (jPanel1 == null) {
+			jPanel1 = new JPanel();
+			jPanel1.add(getJOKButton(), null);
+			jPanel1.add(getJCancelButton(), null);
+		}
+		return jPanel1;
+	}
+
+	/**
+	 * This method initializes jButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJOKButton() {
+		if (jOKButton == null) {
+			jOKButton = new JButton();
+			jOKButton.setText("OK");
+			jOKButton.addActionListener(new java.awt.event.ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					String username=getJUsernameField().getText(); 
+					if(username.length()<4)
+					{
+						javax.swing.JOptionPane.showMessageDialog(
+								AddUserDialog.this,
+								"The username must have at least 4 " +
+								"characters!","Username is too short!",
+								javax.swing.JOptionPane.ERROR_MESSAGE);
+						return;
+					}
+					String password=getJPasswordField().getText();
+					if(password.length()<6)
+					{
+						javax.swing.JOptionPane.showMessageDialog(
+								AddUserDialog.this,
+								"The password must have at least 6 " +
+								"characters! If you still want to set a " +
+								"shorter password, you can change it in the " +
+								"main dialog after setting a correct one.",
+								"Password is too short!",
+								javax.swing.JOptionPane.ERROR_MESSAGE);
+						return;
+					}
+					String realname=getJRealnameField().getText();
+					String email=getJEmailField().getText();
+					String emailsecond=getJEmailSecondField().getText();
+					String homepage=getJHomepageField().getText();
+					String reason=getJReasonTextArea().getText();
+					String notes=getJNotesTextArea().getText();
+					int state = BackedUserData.stateInts[
+                         getJStateComboBox().getSelectedIndex()];
+/*					switch(getJStateComboBox().getSelectedIndex())
+					{
+						case 0: state=BackedUserData.USER_NORMAL; break;
+						case 1: state=BackedUserData.USER_EXPIRED; break;
+						case 2: state=BackedUserData.USER_DEACTIVATED; break;
+						case 3: state=BackedUserData.USER_GROUPADMIN; break;
+						case 4: state=BackedUserData.USER_ADMIN; break;
+						case 5: state=BackedUserData.USER_ADMINNOTIFY; break;
+						case 6: state=BackedUserData.USER_SERVERPAGE; break;
+						default:
+							// how could this happen?
+							javax.swing.JOptionPane.showMessageDialog(
+									AddUserDialog.this,
+									"You selected an invalid state!",
+									"Invalid state!",
+									javax.swing.JOptionPane.ERROR_MESSAGE);
+							return;
+					}*/
+                    
+					Calendar expires;
+					Calendar cal=Calendar.getInstance(
+							TimeZone.getTimeZone("GMT"));
+					try
+					{
+						expires=RequestDialog.parseCalendar(
+								getJExpiresField().getText());
+
+						if(expires!=null)
+						{
+							if(cal.after(expires))
+							{
+								javax.swing.JOptionPane.showMessageDialog(
+										AddUserDialog.this,
+										"Please check the expire date field!",
+										"Expire date is already expired!",
+										javax.swing.JOptionPane.ERROR_MESSAGE);
+								return;
+							}
+						}
+					}
+					catch(ParseException ex)
+					{
+						JOptionPane.showMessageDialog(
+								AddUserDialog.this,
+								"Please check the expire date field!",
+								"Illegal expire date!",
+								JOptionPane.ERROR_MESSAGE);
+						return;
+					}
+
+					
+					// Create BackedUserData object and check the rest
+					
+					BackedUserData data=new BackedUserData(username,password,
+							cal,adminTool.getUsername(),expires,null,0,realname,
+							email,emailsecond,homepage,reason,notes,state);
+					if(!data.checkValid(adminTool.getUserTableModel(),
+							AddUserDialog.this,false)) return;
+					
+					try
+					{
+						adminTool.getJPlagStub().setUserData(
+								new SetUserDataParams(data,null));
+						adminTool.getUserTableModel().addNewUser(data);
+                        adminTool.updateTitle();
+						setVisible(false);
+						return;
+					}
+					catch(Exception ex)
+					{
+						adminTool.CheckException(ex,AddUserDialog.this);
+						return;
+					}
+				}
+			});
+		}
+		return jOKButton;
+	}
+
+	/**
+	 * This method initializes jButton1	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJCancelButton() {
+		if (jCancelButton == null) {
+			jCancelButton = new JButton();
+			jCancelButton.setText("Cancel");
+			jCancelButton.addActionListener(new java.awt.event.ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {    
+					setVisible(false);
+				}
+			});
+		}
+		return jCancelButton;
+	}
+
+	/**
+	 * This method initializes jScrollPane	
+	 * 	
+	 * @return javax.swing.JScrollPane	
+	 */    
+	private JScrollPane getJScrollPane() {
+		if (jScrollPane == null) {
+			jScrollPane = new JScrollPane();
+			jScrollPane.setViewportView(getJNotesTextArea());
+		}
+		return jScrollPane;
+	}
+
+	/**
+	 * This method initializes jScrollPane1	
+	 * 	
+	 * @return javax.swing.JScrollPane	
+	 */    
+	private JScrollPane getJScrollPane1() {
+		if (jScrollPane1 == null) {
+			jScrollPane1 = new JScrollPane();
+			jScrollPane1.setViewportView(getJReasonTextArea());
+		}
+		return jScrollPane1;
+	}
+
+	/**
+	 * This method initializes jTextArea	
+	 * 	
+	 * @return javax.swing.JTextArea	
+	 */    
+	private JTextArea getJReasonTextArea() {
+		if (jReasonTextArea == null) {
+			jReasonTextArea = new JTextArea();
+			jReasonTextArea.setLineWrap(true);
+			jReasonTextArea.setWrapStyleWord(true);
+			jReasonTextArea.setRows(3);
+		}
+		return jReasonTextArea;
+	}
+
+}  //  @jve:decl-index=0:visual-constraint="10,10"

+ 843 - 0
jplag.adminTool/src/main/java/jplagAdminTool/AdminTool.java

@@ -0,0 +1,843 @@
+/*
+ * Created on 20.05.2005
+ * Author: Moritz Kroll
+ */
+
+package jplagAdminTool;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.FontMetrics;
+import java.awt.event.MouseEvent;
+import java.net.MalformedURLException;
+import java.rmi.RemoteException;
+import java.security.cert.X509Certificate;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Vector;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import javax.swing.BorderFactory;
+import javax.swing.DefaultCellEditor;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.ListSelectionModel;
+import javax.swing.border.Border;
+import javax.swing.border.LineBorder;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.JTableHeader;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableColumnModel;
+import javax.xml.rpc.handler.Handler;
+import javax.xml.rpc.handler.HandlerChain;
+
+import jplagUtils.DesktopUtils;
+import jplagUtils.PropertiesLoader;
+import jplagWsClient.jplagClient.JPlagException;
+import jplagWsClient.jplagClient.JPlagService_Impl;
+import jplagWsClient.jplagClient.JPlagTyp_Stub;
+import jplagWsClient.jplagClient.RequestData;
+import jplagWsClient.jplagClient.RequestDataArray;
+import jplagWsClient.jplagClient.SetUserDataParams;
+import jplagWsClient.jplagClient.UserDataArray;
+import jplagWsClient.util.JPlagClientAccessHandler;
+
+public class AdminTool extends JFrame implements TableModelListener {
+	private static final long serialVersionUID = -8979800871645147201L;
+
+	private static final Properties versionProps = PropertiesLoader.loadProps("jplagAdminTool/version.properties");
+	private static final String VERSION_STRING = versionProps.getProperty("version", "devel");
+	private static final String TITLE_STRING = "JPlag AdminTool";
+
+	private JPlagTyp_Stub stub = null;
+	private JPlagClientAccessHandler accessHandler = null;
+
+	private UserTableModel userTableModel = null;
+	private TableSorter tableSorter = null;
+	private Vector changedUsersList = new Vector(3, 5);
+
+	private SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy");
+
+	private javax.swing.JPanel jContentPane = null;
+
+	private JTable jUserTable = null;
+	private JPanel jPanel = null;
+	private JButton jRefreshButton = null;
+
+	private int reqsWaiting = 0;
+	private RequestDialog requestDlg = null;
+
+	private String username = null;
+	private int userstate = 0;
+
+	private JButton jChangePassButton = null;
+
+	private JPanel jPanel1 = null;
+
+	private JScrollPane jScrollPane = null;
+
+	private JButton jAddUserButton = null;
+
+	private JButton jDeleteUserButton = null;
+	private JButton jRequestButton = null;
+	private JButton jServerMailsButton = null;
+	private JButton jDetailsButton = null;
+
+	/**
+	 * This is the default constructor
+	 */
+	public AdminTool() {
+		super();
+
+		// Create a trust manager that does not validate certificate chains
+		TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
+			public X509Certificate[] getAcceptedIssuers() {
+				return null;
+			}
+
+			public void checkClientTrusted(X509Certificate[] certs, String authType) {
+			}
+
+			public void checkServerTrusted(X509Certificate[] certs, String authType) {
+			}
+		} };
+
+		// Install the all-trusting trust manager
+		try {
+			SSLContext sc = SSLContext.getInstance("SSL");
+			sc.init(null, trustAllCerts, new java.security.SecureRandom());
+			HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+		} catch (Exception e) {
+		}
+	}
+
+	/**
+	 * This method initializes this
+	 * 
+	 * @return void
+	 */
+	private void initialize() {
+		setSize(800, 450);
+		setContentPane(getJContentPane());
+		updateTitle();
+	}
+
+	/**
+	 * Updates the program title using the current username and the current
+	 * number of users
+	 */
+	public void updateTitle() {
+		setTitle(TITLE_STRING + " " + VERSION_STRING + " - " + username + " - " + getUserTableModel().getRowCount() + " users");
+	}
+
+	/**
+	 * Returns a singleton JPlag stub
+	 * 
+	 * @return The JPlag stub object
+	 */
+	public JPlagTyp_Stub getJPlagStub() {
+		if (stub == null) {
+			stub = (JPlagTyp_Stub) (new JPlagService_Impl().getJPlagServicePort());
+
+			HandlerChain handlerchain = stub._getHandlerChain();
+			@SuppressWarnings("unchecked")
+			Iterator<Handler> handlers = handlerchain.iterator();
+			while (handlers.hasNext()) {
+				Handler handler = handlers.next();
+				if (handler instanceof JPlagClientAccessHandler) {
+					accessHandler = ((JPlagClientAccessHandler) handler);
+					break;
+				}
+			}
+		}
+		return stub;
+	}
+
+	public String getUsername() {
+		return username;
+	}
+
+	public int getUserState() {
+		return userstate;
+	}
+
+	public void updateLogin(String user, String pass) {
+		accessHandler.setUserPassObjects(user, pass);
+		username = user;
+	}
+
+	/**
+	 * Sets the login data in the access handler, gets the user data array and
+	 * for JPlag admins the account requests and initializes the main window
+	 * starting the real application
+	 * 
+	 * @param user
+	 *            The username
+	 * @param pass
+	 *            The password
+	 * @param window
+	 *            Parent window for error messages
+	 * @return
+	 */
+	public boolean setLogin(String user, String pass, Component window) {
+		username = user;
+		getJPlagStub(); // make sure a stub has been created
+		if (accessHandler == null) {
+			JOptionPane.showMessageDialog(window, "Unable to set login data!", "Access handler not found!", JOptionPane.ERROR_MESSAGE);
+			return false;
+		}
+		accessHandler.setUserPassObjects(user, pass);
+		try {
+			UserDataArray userarray = getJPlagStub().getUserDataArray(0);
+			getUserTableModel().setUserDataArray(userarray);
+			userstate = getUserTableModel().getUserState(username);
+			getUserTableModel().setAdminState(userstate);
+			changedUsersList.clear();
+			if ((userstate & BackedUserData.MASK_JPLAGADMIN) != 0) {
+				reqsWaiting = getJPlagStub().getAccountRequests(true).getItems().length;
+			}
+			initialize();
+			getJAddUserButton().setEnabled(true);
+			return true;
+		} catch (Exception ex) {
+			CheckException(ex, window);
+		}
+		return false;
+	}
+
+	/*
+	 * Some exception evaluation functions
+	 */
+
+	public boolean CheckConnectException(RemoteException re, Component comp) {
+		Throwable cause = re.getCause();
+		if (cause != null && cause instanceof com.sun.xml.rpc.client.ClientTransportException) {
+			cause = ((com.sun.xml.rpc.util.exception.JAXRPCExceptionBase) cause).getLinkedException();
+			if (cause != null) {
+				JOptionPane.showMessageDialog(comp, cause.getMessage(), "Connect exception!", JOptionPane.ERROR_MESSAGE);
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private void CheckRemoteException(java.rmi.RemoteException re, Component comp) {
+		if (!CheckConnectException(re, comp)) {
+			JOptionPane.showMessageDialog(comp, "Unexpected RemoteException: " + re.getMessage(), "Remote exception!",
+					JOptionPane.ERROR_MESSAGE);
+			re.printStackTrace();
+		}
+	}
+
+	public void CheckException(Exception ex, Component comp) {
+		if (ex instanceof JPlagException) {
+			JPlagException jex = (JPlagException) ex;
+			JOptionPane.showMessageDialog(comp, jex.getDescription() + "\n" + jex.getRepair(), jex.getExceptionType(),
+					JOptionPane.ERROR_MESSAGE);
+		} else if (ex instanceof RemoteException) {
+			CheckRemoteException((RemoteException) ex, comp);
+		} else {
+			JOptionPane.showMessageDialog(comp, ex.getMessage(), ex.getClass().getName(), JOptionPane.ERROR_MESSAGE);
+			ex.printStackTrace();
+		}
+	}
+
+	/* end of exception evaluation functions */
+
+	public UserTableModel getUserTableModel() {
+		if (userTableModel == null) {
+			userTableModel = new UserTableModel();
+		}
+		return userTableModel;
+	}
+
+	public boolean userDataChanged(BackedUserData bud) {
+		if (!bud.checkValid(getUserTableModel(), this, true))
+			return false;
+		try {
+			if (username.equals(bud.getOrigUsername()) && (bud.getState() & BackedUserData.MASK_JPLAGADMIN) == 0) {
+				if (JOptionPane.showConfirmDialog(this, "Do you really want to remove your admin rights???\n"
+						+ "You won't be able to undo this without help of\n" + "another admin or access to the server!", "Confirm suicide",
+						JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) {
+					bud.setState(userstate);
+					return false;
+				}
+			}
+
+			getJPlagStub().setUserData(new SetUserDataParams(bud, bud.getOrigUsername()));
+			if (username.equals(bud.getOrigUsername()))
+				updateLogin(bud.getUsername(), bud.getPassword());
+
+			bud.updateBackup();
+			return true;
+		} catch (Exception ex) {
+			CheckException(ex, AdminTool.this);
+			if (ex instanceof JPlagException)
+				bud.resetChanges();
+		}
+		return false;
+	}
+
+	public void tableChanged(TableModelEvent e) {
+		if (e.getColumn() == TableModelEvent.ALL_COLUMNS)
+			return;
+		BackedUserData bud = getUserTableModel().getBackedUserData(e.getFirstRow());
+		userDataChanged(bud);
+	}
+
+	@SuppressWarnings("serial")
+	private class InvalidRenderer extends JLabel implements TableCellRenderer {
+		private final Color LIGHTRED = new Color(255, 128, 128);
+		private final Color VERYLIGHTRED = new Color(255, 204, 204);
+		boolean isBordered = true;
+		Border badFocusBorder = null;
+
+		public InvalidRenderer(boolean isBordered) {
+			this.isBordered = isBordered;
+			setOpaque(true);
+			setFont(getFont().deriveFont(getFont().getStyle() ^ java.awt.Font.BOLD));
+		}
+
+		public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int coloumn) {
+			String str = "";
+			if (obj != null)
+				str = obj.toString();
+			setBackground(isSelected ? VERYLIGHTRED : LIGHTRED);
+
+			if (hasFocus) {
+				if (badFocusBorder == null)
+					badFocusBorder = BorderFactory.createLineBorder(LIGHTRED, 2);
+				setBorder(badFocusBorder);
+			} else
+				setBorder(null);
+			setText(str);
+			return this;
+		}
+	}
+
+	@SuppressWarnings("serial")
+	private class UneditableRenderer extends JLabel implements TableCellRenderer {
+		private final Color LIGHTGRAY = new Color(204, 204, 204);
+		private final Color VERYLIGHTGRAY = new Color(232, 232, 232);
+
+		private boolean isDate;
+
+		public UneditableRenderer(boolean isDate) {
+			this.isDate = isDate;
+			setOpaque(true);
+			setFont(getFont().deriveFont(getFont().getStyle() ^ java.awt.Font.BOLD));
+		}
+
+		public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int column) {
+			setBackground(isSelected ? LIGHTGRAY : VERYLIGHTGRAY);
+			if (isDate)
+				setText(obj == null ? "No date" : dateFormatter.format((Date) obj));
+			else
+				setText(obj == null ? "" : obj.toString());
+			return this;
+		}
+	}
+
+	@SuppressWarnings("serial")
+	private class DateRenderer extends DefaultTableCellRenderer {
+		public void setValue(Object value) {
+			setText((value == null) ? "No date" : dateFormatter.format((Date) value));
+		}
+	}
+
+	@SuppressWarnings("serial")
+	private class DateEditor extends DefaultCellEditor {
+		public DateEditor() {
+			super(new JTextField());
+		}
+
+		public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
+			((JComponent) getComponent()).setBorder(new LineBorder(Color.black));
+			return super.getTableCellEditorComponent(table, value == null ? "" : dateFormatter.format((Date) value), isSelected, row,
+					column);
+		}
+	}
+
+	/**
+	 * This method initializes jUserTable
+	 * 
+	 * @return javax.swing.JTable
+	 */
+	@SuppressWarnings("serial")
+	private JTable getJUserTable() {
+		if (jUserTable == null) {
+			tableSorter = new TableSorter(getUserTableModel());
+			jUserTable = new JTable(tableSorter) {
+				TableCellRenderer invalidRenderer = new InvalidRenderer(false);
+				TableCellRenderer uneditableRenderer[] = new TableCellRenderer[] { new UneditableRenderer(false),
+						new UneditableRenderer(true) };
+				TableCellRenderer dateRenderer = new DateRenderer();
+
+				public TableCellRenderer getCellRenderer(int row, int column) {
+					int modrow = tableSorter.modelIndex(row);
+					int modcol = convertColumnIndexToModel(column);
+					int isdateind = getUserTableModel().isDate(modcol) ? 1 : 0;
+					if (!getUserTableModel().isValid(modrow, modcol))
+						return invalidRenderer;
+					if (!getUserTableModel().isCellEditable(modrow, modcol))
+						return uneditableRenderer[isdateind];
+					if (isdateind == 1)
+						return dateRenderer;
+					return super.getCellRenderer(row, column);
+				}
+
+				protected JTableHeader createDefaultTableHeader() {
+					return new JTableHeader(columnModel) {
+						public String getToolTipText(MouseEvent e) {
+							int index = columnModel.getColumnIndexAtX(e.getPoint().x);
+							int realIndex = columnModel.getColumn(index).getModelIndex();
+							if (realIndex == UserTableModel.NUMSUBS)
+								return "The number of submissions this user posted";
+							return null;
+						}
+					};
+				}
+			};
+			jUserTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+			ListSelectionModel rowSM = jUserTable.getSelectionModel();
+			rowSM.addListSelectionListener(new ListSelectionListener() {
+				public void valueChanged(ListSelectionEvent e) {
+					if (e.getValueIsAdjusting())
+						return;
+					ListSelectionModel lsm = (ListSelectionModel) e.getSource();
+					getJChangePassButton().setEnabled(!lsm.isSelectionEmpty());
+					getJDetailsButton().setEnabled(!lsm.isSelectionEmpty());
+					getJDeleteUserButton().setEnabled(!lsm.isSelectionEmpty());
+				}
+			});
+			getUserTableModel().addTableModelListener(this);
+			getUserTableModel().addTableModelListener(jUserTable);
+
+			tableSorter.setTableHeader(jUserTable.getTableHeader());
+
+			TableColumnModel tcm = jUserTable.getColumnModel();
+			TableColumn col = tcm.getColumn(UserTableModel.STATE);
+			JComboBox<String> comboBox = new JComboBox<String>(BackedUserData.getStateNameArray(userstate));
+			comboBox.setBackground(Color.WHITE);
+			comboBox.setFont(comboBox.getFont().deriveFont(comboBox.getFont().getStyle() ^ java.awt.Font.BOLD));
+			col.setCellEditor(new DefaultCellEditor(comboBox));
+			col.setMaxWidth(92);
+			col.setPreferredWidth(92);
+
+			col = tcm.getColumn(UserTableModel.CREATED);
+			col.setCellEditor(new DateEditor());
+			col = tcm.getColumn(UserTableModel.EXPIRES);
+			col.setCellEditor(new DateEditor());
+			col = tcm.getColumn(UserTableModel.LASTUSAGE);
+			col.setCellEditor(new DateEditor());
+
+			FontMetrics fm = jUserTable.getFontMetrics(jUserTable.getFont());
+
+			int dateWidth = fm.stringWidth("88.88.8888") + 4;
+			col = tcm.getColumn(UserTableModel.CREATED);
+			col.setMaxWidth(dateWidth);
+			col = tcm.getColumn(UserTableModel.EXPIRES);
+			col.setMaxWidth(dateWidth);
+			col = tcm.getColumn(UserTableModel.LASTUSAGE);
+			col.setMaxWidth(dateWidth);
+			col = tcm.getColumn(UserTableModel.NUMSUBS);
+			col.setMaxWidth(32);
+
+			col = tcm.getColumn(UserTableModel.CREATEDBY);
+			col.setPreferredWidth(50);
+
+			jUserTable.setRowHeight(20);
+		}
+		return jUserTable;
+	}
+
+	/**
+	 * This method initializes jContentPane
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	private javax.swing.JPanel getJContentPane() {
+		if (jContentPane == null) {
+			jContentPane = new javax.swing.JPanel();
+			jContentPane.setLayout(new java.awt.BorderLayout());
+			jContentPane.add(getJScrollPane(), java.awt.BorderLayout.CENTER);
+			jContentPane.add(getJPanel1(), java.awt.BorderLayout.SOUTH);
+			jContentPane.add(getJPanel(), java.awt.BorderLayout.NORTH);
+		}
+		return jContentPane;
+	}
+
+	/**
+	 * This method initializes jPanel
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getJPanel() {
+		if (jPanel == null) {
+			jPanel = new JPanel();
+			jPanel.add(getJRefreshButton(), null);
+			if ((userstate & BackedUserData.MASK_JPLAGADMIN) != 0) {
+				jPanel.add(getJRequestButton(), null);
+				jPanel.add(getJServerMailsButton(), null);
+			}
+		}
+		return jPanel;
+	}
+
+	/**
+	 * This method initializes jRefreshButton
+	 * 
+	 * @return javax.swing.JButton
+	 */
+	private JButton getJRefreshButton() {
+		if (jRefreshButton == null) {
+			jRefreshButton = new JButton();
+			jRefreshButton.setText("Refresh");
+			jRefreshButton.addActionListener(new java.awt.event.ActionListener() {
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					final SwingWorker worker = new SwingWorker() {
+						private UserDataArray userarray = null;
+						private RequestDataArray reqarray = null;
+
+						public Object construct() {
+							try {
+								userarray = getJPlagStub().getUserDataArray(0);
+								reqarray = getJPlagStub().getAccountRequests(true);
+							} catch (Exception ex) {
+								CheckException(ex, AdminTool.this);
+							}
+							return null;
+						}
+
+						public void finished() {
+							// Update user list
+
+							if (userarray != null) {
+								getUserTableModel().setUserDataArray(userarray);
+								updateTitle();
+							}
+							changedUsersList.clear();
+							getJAddUserButton().setEnabled(true);
+
+							if ((userstate & BackedUserData.MASK_JPLAGADMIN) != 0) {
+								// Update "Check requests" button
+
+								if (reqarray != null) {
+									RequestData[] rds = reqarray.getItems();
+									if (rds != null)
+										reqsWaiting = rds.length;
+									else
+										reqsWaiting = 0;
+								} else
+									reqsWaiting = 0;
+								jRequestButton.setText("Check requests (" + reqsWaiting + " waiting)");
+							}
+						}
+					};
+					worker.start();
+				}
+			});
+		}
+		return jRefreshButton;
+	}
+
+	/**
+	 * This method initializes jChangePassButton
+	 * 
+	 * @return javax.swing.JButton
+	 */
+	private JButton getJChangePassButton() {
+		if (jChangePassButton == null) {
+			jChangePassButton = new JButton();
+			jChangePassButton.setText("Change user password");
+			jChangePassButton.setEnabled(false);
+			jChangePassButton.addActionListener(new java.awt.event.ActionListener() {
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					int row = tableSorter.modelIndex(getJUserTable().getSelectedRow());
+					int col = getJUserTable().getSelectedColumn();
+					if (row < 0 || col < 0) {
+						JOptionPane.showMessageDialog(AdminTool.this, "Please select a user first!", "No user selected!",
+								JOptionPane.ERROR_MESSAGE);
+						return;
+					}
+					PassDialog pd = new PassDialog(getUserTableModel().getBackedUserData(row), AdminTool.this);
+					pd.pack();
+					pd.setLocationRelativeTo(AdminTool.this);
+					pd.setVisible(true);
+				}
+			});
+		}
+		return jChangePassButton;
+	}
+
+	/**
+	 * This method initializes jPanel1
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getJPanel1() {
+		if (jPanel1 == null) {
+			jPanel1 = new JPanel();
+			jPanel1.add(getJChangePassButton(), null);
+			jPanel1.add(getJDetailsButton(), null);
+			jPanel1.add(getJAddUserButton(), null);
+			jPanel1.add(getJDeleteUserButton(), null);
+		}
+		return jPanel1;
+	}
+
+	/**
+	 * This method initializes jScrollPane
+	 * 
+	 * @return javax.swing.JScrollPane
+	 */
+	private JScrollPane getJScrollPane() {
+		if (jScrollPane == null) {
+			jScrollPane = new JScrollPane();
+			jScrollPane.setViewportView(getJUserTable());
+		}
+		return jScrollPane;
+	}
+
+	/**
+	 * This method initializes jAddUserButton
+	 * 
+	 * @return javax.swing.JButton
+	 */
+	private JButton getJAddUserButton() {
+		if (jAddUserButton == null) {
+			jAddUserButton = new JButton();
+			jAddUserButton.setText("Add new user");
+			jAddUserButton.setEnabled(false);
+			jAddUserButton.addActionListener(new java.awt.event.ActionListener() {
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					AddUserDialog aud = new AddUserDialog(AdminTool.this);
+					aud.pack();
+					aud.setLocationRelativeTo(AdminTool.this);
+					aud.setVisible(true);
+				}
+			});
+		}
+		return jAddUserButton;
+	}
+
+	/**
+	 * This method initializes jDeleteUserButton
+	 * 
+	 * @return javax.swing.JButton
+	 */
+	private JButton getJDeleteUserButton() {
+		if (jDeleteUserButton == null) {
+			jDeleteUserButton = new JButton();
+			jDeleteUserButton.setText("Delete user");
+			jDeleteUserButton.setEnabled(false);
+			jDeleteUserButton.addActionListener(new java.awt.event.ActionListener() {
+				BackedUserData bud;
+
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					final SwingWorker worker = new SwingWorker() {
+						public Object construct() {
+							try {
+								bud.setUsername(null);
+								getJPlagStub().setUserData(new SetUserDataParams(bud, bud.getOrigUsername()));
+							} catch (Exception ex) {
+								CheckException(ex, AdminTool.this);
+							}
+							return null;
+						}
+
+						public void finished() {
+							getUserTableModel().removeUser(bud.getOrigUsername());
+							updateTitle();
+						}
+					};
+
+					int row = tableSorter.modelIndex(getJUserTable().getSelectedRow());
+					int col = getJUserTable().getSelectedColumn();
+					if (row < 0 || col < 0) {
+						JOptionPane.showMessageDialog(AdminTool.this, "Please select a user first!", "No user selected!",
+								JOptionPane.ERROR_MESSAGE);
+						return;
+					}
+					bud = getUserTableModel().getBackedUserData(row);
+					if (JOptionPane.showConfirmDialog(AdminTool.this, "Do you really want to delete the user \"" + bud.getOrigUsername()
+							+ "\"?\nAll files related " + "to this user will be deleted!", "Confirm deletion", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
+						worker.start();
+				}
+			});
+		}
+		return jDeleteUserButton;
+	}
+
+	/**
+	 * This method initializes jRequestButton
+	 * 
+	 * @return javax.swing.JButton
+	 */
+	private JButton getJRequestButton() {
+		if (jRequestButton == null) {
+			jRequestButton = new JButton();
+			jRequestButton.setText("Check requests (" + reqsWaiting + " waiting)");
+			jRequestButton.addActionListener(new java.awt.event.ActionListener() {
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					final SwingWorker worker = new SwingWorker() {
+						private RequestDataArray reqarray = null;
+
+						public Object construct() {
+							try {
+								reqarray = getJPlagStub().getAccountRequests(false);
+							} catch (Exception ex) {
+								CheckException(ex, AdminTool.this);
+							}
+							return null;
+						}
+
+						public void finished() {
+							RequestData[] rds = reqarray.getItems();
+							if (rds != null)
+								reqsWaiting = rds.length;
+							else
+								reqsWaiting = 0;
+							jRequestButton.setText("Check requests (" + reqsWaiting + " waiting)");
+							if (reqsWaiting != 0) {
+								if (requestDlg != null && requestDlg.isVisible())
+									requestDlg.requestFocus();
+								else {
+									requestDlg = new RequestDialog(rds, AdminTool.this);
+									requestDlg.pack();
+									requestDlg.setLocationRelativeTo(AdminTool.this);
+									requestDlg.setVisible(true);
+								}
+							} else {
+								JOptionPane.showMessageDialog(AdminTool.this, "No request is waiting for you!", "No requests available!",
+										JOptionPane.INFORMATION_MESSAGE);
+							}
+						}
+					};
+					worker.start();
+				}
+			});
+		}
+		return jRequestButton;
+	}
+
+	public void updateRequestsWaiting() {
+		final SwingWorker worker = new SwingWorker() {
+			private RequestDataArray reqarray = null;
+
+			public Object construct() {
+				try {
+					reqarray = getJPlagStub().getAccountRequests(true);
+				} catch (Exception ex) {
+					CheckException(ex, AdminTool.this);
+				}
+				return null;
+			}
+
+			public void finished() {
+				RequestData[] rds = reqarray.getItems();
+				if (rds != null) {
+					reqsWaiting = rds.length;
+				} else {
+					reqsWaiting = 0;
+				}
+				jRequestButton.setText("Check requests (" + reqsWaiting + " waiting)");
+			}
+		};
+		worker.start();
+	}
+
+	/**
+	 * This method initializes jServerMailsButton
+	 * 
+	 * @return javax.swing.JButton
+	 */
+	private JButton getJServerMailsButton() {
+		if (jServerMailsButton == null) {
+			jServerMailsButton = new JButton();
+			jServerMailsButton.setText("Change mail templates");
+			jServerMailsButton.addActionListener(new java.awt.event.ActionListener() {
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					RequestData rd = new RequestData(null, "Matze", "UlTiMaTePaSs", "Mathias Musterknabe", "Matze@email.server",
+							"Mathias@email2.server2", "www.Matze-Musterknabe-Page.xyz", "Toller Grund ohne wenn und aber", "Wenn und aber");
+					MailDialog md = new MailDialog(MailDialog.MAIL_ALL, "Change mail templates...", rd, AdminTool.this);
+					md.setVisible(true);
+				}
+			});
+		}
+		return jServerMailsButton;
+	}
+
+	/**
+	 * This method initializes jDetailsButton
+	 * 
+	 * @return javax.swing.JButton
+	 */
+	private JButton getJDetailsButton() {
+		if (jDetailsButton == null) {
+			jDetailsButton = new JButton();
+			jDetailsButton.setText("Change user details");
+			jDetailsButton.setEnabled(false);
+			jDetailsButton.addActionListener(new java.awt.event.ActionListener() {
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					int row = tableSorter.modelIndex(getJUserTable().getSelectedRow());
+					int col = getJUserTable().getSelectedColumn();
+					if (row < 0 || col < 0) {
+						JOptionPane.showMessageDialog(AdminTool.this, "Please select a user first!", "No user selected!",
+								JOptionPane.ERROR_MESSAGE);
+						return;
+					}
+					DetailsDialog dd = new DetailsDialog(getUserTableModel().getBackedUserData(row), AdminTool.this);
+					dd.pack();
+					dd.setLocationRelativeTo(AdminTool.this);
+					dd.setVisible(true);
+				}
+			});
+		}
+		return jDetailsButton;
+	}
+
+	// TODO #44
+	public static void showHomepage(String url, Component parent) {
+		if (DesktopUtils.isBrowseSupported()) {
+			try {
+				DesktopUtils.openWebpage(url);
+			} catch (MalformedURLException e) {
+
+			}
+		} else {
+			JOptionPane.showMessageDialog(parent, "Couldn't open homepage in browser!", "Browser problem", JOptionPane.ERROR_MESSAGE);
+		}
+	}
+
+	public static void main(String[] args) {
+		javax.swing.SwingUtilities.invokeLater(new Runnable() {
+			public void run() {
+				JFrame owner = new JFrame("JPlag AdminTool login dialog");
+				owner.setLocation(-1000, -1000);
+				owner.setVisible(true);
+				LoginDialog ld = new LoginDialog(owner);
+				ld.setLocationRelativeTo(null);
+				ld.setVisible(true);
+			}
+		});
+	}
+} //  @jve:decl-index=0:visual-constraint="10,10"

+ 255 - 0
jplag.adminTool/src/main/java/jplagAdminTool/BackedUserData.java

@@ -0,0 +1,255 @@
+package jplagAdminTool;
+
+import java.awt.Component;
+import java.util.Calendar;
+
+import javax.swing.JOptionPane;
+
+import jplagWsClient.jplagClient.UserData;
+
+public class BackedUserData extends UserData {
+	public static final int USER_INVALID = 0;
+	public static final int USER_NORMAL = 1;
+	public static final int USER_EXPIRED = 5;
+	public static final int USER_DEACTIVATED = 9;
+	public static final int USER_GROUPADMIN = 64;
+	public static final int USER_JPLAGADMIN = 192;
+	public static final int USER_JPLAGADMINNOTIFY = 224; // with email notification
+	public static final int USER_SERVERPAGE = 256;
+
+    public static final int MASK_DEVELOPER = 2;
+    public static final int MASK_EXPIRED = 4;
+    public static final int MASK_DEACTIVATED = 8;
+    public static final int MASK_REQUESTNOTIFY = 32;
+    public static final int MASK_ANYADMIN = 64;
+	public static final int MASK_JPLAGADMIN = 128;
+    public static final int MASK_SERVERPAGE = 256;
+    public static final int MASK_NOAUTOASKEXTEND = 512;
+
+	public static final String[] stateStrings = {
+        "Normal", "NormalDev", "Trial",
+        "Expired", "ExpiredDev", "ExpiredTrial", "Deactivated", "DeactivDev",
+        "DeactiveTrial", "GroupAdmin", "GrpAdminDev",
+        "JPlagAdmin", "JPAdminDev", "JPAdminNotify",
+        "JPAdNotifyDev", "JPlagJSP"	};
+	public static final int[] stateInts = {
+        USER_NORMAL, USER_NORMAL | MASK_DEVELOPER,
+        USER_NORMAL | MASK_NOAUTOASKEXTEND,
+        USER_EXPIRED, USER_EXPIRED | MASK_DEVELOPER,
+        USER_EXPIRED | MASK_NOAUTOASKEXTEND,
+        USER_DEACTIVATED, USER_DEACTIVATED | MASK_DEVELOPER,
+        USER_DEACTIVATED | MASK_NOAUTOASKEXTEND,
+        USER_GROUPADMIN, USER_GROUPADMIN | MASK_DEVELOPER,
+        USER_JPLAGADMIN, USER_JPLAGADMIN | MASK_DEVELOPER,
+        USER_JPLAGADMINNOTIFY, USER_JPLAGADMINNOTIFY | MASK_DEVELOPER,
+		USER_SERVERPAGE };
+	
+	public static final String[] stateStringsGrpAdmin = { "Normal", "NormalDev",
+        "Expired", "ExpiredDev", "Deactivated", "DeactivDev" };
+	
+	private UserData backup = new UserData();
+
+    public BackedUserData(String username, String password, Calendar created,
+			String createdBy, Calendar expires, Calendar lastUsage, 
+			int numOfSubs, String realName, String email, String emailSecond,
+			String homepage, String reason, String notes, int state) {
+        this.username = username;
+        this.password = password;
+        this.created = created;
+        this.createdBy = createdBy;
+        this.expires = expires;
+        this.lastUsage = lastUsage;
+        this.numOfSubs = numOfSubs;
+        this.realName = realName;
+        this.email = email;
+        this.emailSecond = emailSecond;
+        this.homepage = homepage;
+		this.reason = reason;
+        this.notes = notes;
+        this.state = state;
+		updateBackup();
+    }
+	
+	public BackedUserData(UserData data) {
+		setData(data);
+		updateBackup();
+	}
+	
+	public static String[] getStateNameArray(int adminstate) {
+		if((adminstate & MASK_JPLAGADMIN)!=0) return stateStrings;
+		else return stateStringsGrpAdmin;
+	}
+	
+	public static String getStateName(int state) {
+		for(int i=0;i<stateInts.length;i++)
+			if(stateInts[i]==state) return stateStrings[i];
+		return "INVALID (" + state + ")";
+	}
+	
+	public static int getStateInt(String str) {
+		for(int i=0;i<stateInts.length;i++)
+			if(stateStrings[i].equals(str)) return stateInts[i];
+		return USER_INVALID;
+	}
+	
+	private void setData(UserData data) {
+		this.username = data.getUsername();
+        this.password = data.getPassword();
+        this.created = data.getCreated();
+		this.createdBy = data.getCreatedBy();
+        this.expires = data.getExpires();
+        this.lastUsage = data.getLastUsage();
+        this.numOfSubs = data.getNumOfSubs();
+		this.realName = data.getRealName();
+        this.email = data.getEmail();
+		this.emailSecond = data.getEmailSecond();
+        this.homepage = data.getHomepage();
+		this.reason = data.getReason();
+        this.notes = data.getNotes();
+        this.state = data.getState();
+	}
+	
+	public void updateBackup() {
+		backup.setUsername(username);
+		backup.setPassword(password);
+		backup.setCreated(created);
+		backup.setCreatedBy(createdBy);
+		backup.setExpires(expires);
+		backup.setLastUsage(lastUsage);
+		backup.setNumOfSubs(numOfSubs);
+		backup.setRealName(realName);
+		backup.setEmail(email);
+		backup.setEmailSecond(emailSecond);
+		backup.setHomepage(homepage);
+		backup.setReason(reason);
+		backup.setNotes(notes);
+		backup.setState(state);
+	}
+	
+	public void resetChanges() {
+		setData(backup);
+	}
+	
+	public String getOrigUsername() {
+		return backup.getUsername();
+	}
+	
+	public boolean checkValid(UserTableModel utm, Component comp,
+			boolean reset) {
+		if(username.length()==0)
+		{
+			JOptionPane.showMessageDialog(
+					comp,"You have to provide a username!",
+					"Illegal username!",
+					JOptionPane.ERROR_MESSAGE);
+			if(reset) username=backup.getUsername();
+			return false;
+		}
+		if(!username.equals(backup.getUsername()))
+		{
+			if(utm.existsDoubled(username))
+			{
+				JOptionPane.showMessageDialog(
+						comp, "Please choose another username!",
+						"Username already exists!",
+						JOptionPane.ERROR_MESSAGE);
+				if(reset) username=backup.getUsername();
+				return false;
+			}
+			if((utm.getAdminState() & MASK_JPLAGADMIN)==0	// is group admin?
+					&& username.length()<4)
+			{
+				JOptionPane.showMessageDialog(comp, "The username must have at"
+						+ " least 4 characters!", "Username is too short!",
+						JOptionPane.ERROR_MESSAGE);
+				if(reset) username=backup.getUsername();
+				return false;
+			}
+		}
+		if(!password.equals(backup.getPassword()) && password.length()<3)
+		{
+			JOptionPane.showMessageDialog(
+					comp, "A forced short password must have at least 3 "
+					+ "characters!", "Password is REALLY too short!",
+					JOptionPane.ERROR_MESSAGE);
+			if(reset) password=backup.getPassword();
+			return false;
+		}
+		if(createdBy==null || createdBy.length()==0)
+		{
+			JOptionPane.showMessageDialog(
+					comp ,"You must provide a \"createdBy\" name!",
+					"Illegal \"createdBy\" name!",
+					JOptionPane.ERROR_MESSAGE);
+			if(reset) password=backup.getPassword();
+			return false;
+		}
+		String tokens[]=realName.split(" ");
+		if(realName.length()<3 || tokens.length<2) {
+			JOptionPane.showMessageDialog(
+					comp, "The realname has to contain at least a fore- " +
+					"and a surename!", "Invalid realname!",
+					JOptionPane.ERROR_MESSAGE);
+			if(reset) realName=backup.getRealName();
+			return false;
+		}
+		String tokens1[]=email.split("@");
+		boolean emailOK=false;
+		if(tokens1.length==2)
+		{
+			String tokens2[]=tokens1[1].split("\\.");
+			if(tokens2.length>=2) emailOK=true;
+		}
+		if(!emailOK)
+		{
+			JOptionPane.showMessageDialog(
+					comp, "The email address does not " +
+					"fit into the form <user>@<domain>.<suffix>!",
+					"Invalid primary email address!",
+					JOptionPane.ERROR_MESSAGE);
+			if(reset) email=backup.getEmail();
+			return false;
+		}
+		if(emailSecond!=null && emailSecond.length()!=0)
+		{
+			String tokens3[]=emailSecond.split("@");
+			boolean emailsecondOK=false;
+			if(tokens3.length==2)
+			{
+				String tokens2[]=tokens3[1].split("\\.");
+				if(tokens2.length>=2) emailsecondOK=true;
+			}
+			if(!emailsecondOK)
+			{
+				JOptionPane.showMessageDialog(
+					comp, "The email address is not empty " +
+					"and does not fit into the form " +
+					"<user>@<domain>.<suffix>!",
+					"Invalid secondary email address!",
+					JOptionPane.ERROR_MESSAGE);
+				if(reset) emailSecond=backup.getEmailSecond();
+				return false;
+			}	
+		}
+		switch(state & ~(MASK_DEVELOPER | MASK_NOAUTOASKEXTEND))
+		{
+			case USER_NORMAL:
+			case USER_EXPIRED:
+			case USER_DEACTIVATED:
+			case USER_GROUPADMIN:
+			case USER_JPLAGADMIN:
+			case USER_JPLAGADMINNOTIFY:
+			case USER_SERVERPAGE:
+				break;
+			default:
+				// how could this happen?
+				JOptionPane.showMessageDialog(
+						comp, "You selected an invalid state (" + state + ")!",
+						"Invalid state!",
+						JOptionPane.ERROR_MESSAGE);
+				if(reset) state=backup.getState();
+				return false;
+		}
+		return true;
+	}
+}

+ 344 - 0
jplag.adminTool/src/main/java/jplagAdminTool/DetailsDialog.java

@@ -0,0 +1,344 @@
+package jplagAdminTool;
+
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRootPane;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.KeyStroke;
+
+public class DetailsDialog extends JDialog {
+	private static final long serialVersionUID = -4082825477146193323L;
+
+	private javax.swing.JPanel jContentPane = null;
+
+	private BackedUserData data;
+	private AdminTool adminTool;
+
+	private JLabel jLabel = null;
+
+	private JTextField jEmail2ndTextField = null;
+
+	private JLabel jLabel1 = null;
+
+	private JTextField jHomepageTextField = null;
+
+	private JLabel jLabel2 = null;
+
+	private JScrollPane jScrollPane = null;
+
+	private JTextArea jReasonTextArea = null;
+
+	private JLabel jLabel3 = null;
+
+	private JScrollPane jScrollPane1 = null;
+
+	private JTextArea jNotesTextArea = null;
+
+	private JPanel jPanel = null;
+
+	private JButton jApplyButton = null;
+
+	private JButton jCancelButton = null;
+
+    private JButton jShowHomepageButton = null;
+	
+	/**
+	 * This is the default constructor
+	 */
+	public DetailsDialog(BackedUserData ud, AdminTool parent) {
+		super(parent,true);
+		data=ud;
+		adminTool=parent;
+		initialize();
+	}
+
+	protected JRootPane createRootPane() {
+		KeyStroke stroke=KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
+		JRootPane rootPane=new JRootPane();
+		rootPane.registerKeyboardAction(new ActionListener() {
+				public void actionPerformed(ActionEvent actionEvent) {
+					setVisible(false);
+                    dispose();
+				}
+			}, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
+		
+		return rootPane;
+	}
+	
+	/**
+	 * This method initializes this
+	 * 
+	 * @return void
+	 */
+	private void initialize() {
+		this.setSize(417, 276);
+		this.setTitle("Details for user \"" + data.getUsername() + "\"");
+		this.setContentPane(getJContentPane());
+	}
+
+	/**
+	 * This method initializes jContentPane
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	private javax.swing.JPanel getJContentPane() {
+		if(jContentPane == null) {
+			GridBagConstraints gridBagConstraints = new GridBagConstraints();
+			gridBagConstraints.gridx = 2;
+			gridBagConstraints.gridy = 1;
+			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
+			gridBagConstraints11.gridx = 0;
+			gridBagConstraints11.gridy = 4;
+			gridBagConstraints11.gridwidth = 3;
+			gridBagConstraints11.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints11.insets = new java.awt.Insets(5,0,0,0);
+			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
+			gridBagConstraints10.fill = java.awt.GridBagConstraints.BOTH;
+			gridBagConstraints10.gridx = 1;
+			gridBagConstraints10.gridy = 3;
+			gridBagConstraints10.weightx = 1.0;
+			gridBagConstraints10.gridwidth = 2;
+			gridBagConstraints10.weighty = 1.0;
+			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
+			gridBagConstraints9.gridx = 0;
+			gridBagConstraints9.gridy = 3;
+			gridBagConstraints9.anchor = java.awt.GridBagConstraints.NORTHWEST;
+			jLabel3 = new JLabel();
+			jLabel3.setText("Notes:");
+			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
+			gridBagConstraints8.fill = java.awt.GridBagConstraints.BOTH;
+			gridBagConstraints8.gridx = 1;
+			gridBagConstraints8.gridy = 2;
+			gridBagConstraints8.weightx = 1.0;
+			gridBagConstraints8.gridwidth = 2;
+			gridBagConstraints8.weighty = 1.0;
+			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
+			gridBagConstraints7.gridx = 0;
+			gridBagConstraints7.gridy = 2;
+			gridBagConstraints7.anchor = java.awt.GridBagConstraints.NORTHWEST;
+			jLabel2 = new JLabel();
+			jLabel2.setText("Reason:");
+			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
+			gridBagConstraints6.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints6.gridx = 1;
+			gridBagConstraints6.gridy = 1;
+			gridBagConstraints6.weightx = 1.0;
+			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
+			gridBagConstraints5.gridx = 0;
+			gridBagConstraints5.gridy = 1;
+			gridBagConstraints5.anchor = java.awt.GridBagConstraints.WEST;
+			gridBagConstraints5.insets = new java.awt.Insets(0,0,0,5);
+			jLabel1 = new JLabel();
+			jLabel1.setText("Homepage:");
+			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
+			gridBagConstraints4.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints4.gridx = 1;
+			gridBagConstraints4.gridy = 0;
+			gridBagConstraints4.gridwidth = 2;
+			gridBagConstraints4.weightx = 1.0;
+			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
+			gridBagConstraints3.gridx = 0;
+			gridBagConstraints3.gridy = 0;
+			gridBagConstraints3.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel = new JLabel();
+			jLabel.setText("2. Email:");
+			jContentPane = new javax.swing.JPanel();
+			jContentPane.setLayout(new GridBagLayout());
+			jContentPane.setBorder(javax.swing.BorderFactory.createEmptyBorder(5,5,5,5));
+			jContentPane.add(getJPanel(), gridBagConstraints11);
+			jContentPane.add(getJScrollPane1(), gridBagConstraints10);
+			jContentPane.add(jLabel3, gridBagConstraints9);
+			jContentPane.add(getJScrollPane(), gridBagConstraints8);
+			jContentPane.add(jLabel2, gridBagConstraints7);
+			jContentPane.add(jLabel, gridBagConstraints3);
+			jContentPane.add(getJHomepageTextField(), gridBagConstraints6);
+			jContentPane.add(getJEmail2ndTextField(), gridBagConstraints4);
+			jContentPane.add(jLabel1, gridBagConstraints5);
+			jContentPane.add(getJShowHomepageButton(), gridBagConstraints);
+		}
+		return jContentPane;
+	}
+
+	/**
+	 * This method initializes jTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJEmail2ndTextField() {
+		if (jEmail2ndTextField == null) {
+			jEmail2ndTextField = new JTextField();
+			jEmail2ndTextField.setText(data.getEmailSecond());
+			jEmail2ndTextField.setPreferredSize(new java.awt.Dimension(300,20));
+		}
+		return jEmail2ndTextField;
+	}
+
+	/**
+	 * This method initializes jTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJHomepageTextField() {
+		if (jHomepageTextField == null) {
+			jHomepageTextField = new JTextField();
+			jHomepageTextField.setText(data.getHomepage());
+		}
+		return jHomepageTextField;
+	}
+
+	/**
+	 * This method initializes jScrollPane	
+	 * 	
+	 * @return javax.swing.JScrollPane	
+	 */    
+	private JScrollPane getJScrollPane() {
+		if (jScrollPane == null) {
+			jScrollPane = new JScrollPane();
+			jScrollPane.setViewportView(getJReasonTextArea());
+		}
+		return jScrollPane;
+	}
+
+	/**
+	 * This method initializes jTextArea	
+	 * 	
+	 * @return javax.swing.JTextArea	
+	 */    
+	private JTextArea getJReasonTextArea() {
+		if (jReasonTextArea == null) {
+			jReasonTextArea = new JTextArea();
+			jReasonTextArea.setText(data.getReason());
+			jReasonTextArea.setLineWrap(true);
+			jReasonTextArea.setWrapStyleWord(true);
+			jReasonTextArea.setRows(7);
+            jReasonTextArea.setCaretPosition(0);
+		}
+		return jReasonTextArea;
+	}
+
+	/**
+	 * This method initializes jScrollPane1	
+	 * 	
+	 * @return javax.swing.JScrollPane	
+	 */    
+	private JScrollPane getJScrollPane1() {
+		if (jScrollPane1 == null) {
+			jScrollPane1 = new JScrollPane();
+			jScrollPane1.setViewportView(getJNotesTextArea());
+		}
+		return jScrollPane1;
+	}
+
+	/**
+	 * This method initializes jTextArea1	
+	 * 	
+	 * @return javax.swing.JTextArea	
+	 */    
+	private JTextArea getJNotesTextArea() {
+		if (jNotesTextArea == null) {
+			jNotesTextArea = new JTextArea();
+			jNotesTextArea.setText(data.getNotes());
+			jNotesTextArea.setLineWrap(true);
+			jNotesTextArea.setWrapStyleWord(true);
+			jNotesTextArea.setRows(6);
+            jNotesTextArea.setCaretPosition(0);
+		}
+		return jNotesTextArea;
+	}
+
+	/**
+	 * This method initializes jPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */    
+	private JPanel getJPanel() {
+		if (jPanel == null) {
+			FlowLayout flowLayout12 = new FlowLayout();
+			flowLayout12.setVgap(0);
+			jPanel = new JPanel();
+			jPanel.setLayout(flowLayout12);
+			jPanel.add(getJApplyButton(), null);
+			jPanel.add(getJCancelButton(), null);
+		}
+		return jPanel;
+	}
+
+	/**
+	 * This method initializes jButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJApplyButton() {
+		if (jApplyButton == null) {
+			jApplyButton = new JButton();
+			jApplyButton.setText("Apply");
+			jApplyButton.addActionListener(new java.awt.event.ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {    
+					data.setEmailSecond(getJEmail2ndTextField().getText());
+					data.setHomepage(getJHomepageTextField().getText());
+					data.setReason(getJReasonTextArea().getText());
+					data.setNotes(getJNotesTextArea().getText());
+					if(adminTool.userDataChanged(data)) {
+						setVisible(false);
+                        dispose();
+                    }
+				}
+			});
+		}
+		return jApplyButton;
+	}
+
+	/**
+	 * This method initializes jButton1	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJCancelButton() {
+		if (jCancelButton == null) {
+			jCancelButton = new JButton();
+			jCancelButton.setText("Cancel");
+			jCancelButton.addActionListener(new java.awt.event.ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {    
+					setVisible(false);
+                    dispose();
+				}
+			});
+		}
+		return jCancelButton;
+	}
+
+    /**
+     * This method initializes jShowHomepageButton	
+     * 	
+     * @return javax.swing.JButton	
+     */
+    private JButton getJShowHomepageButton() {
+        if(jShowHomepageButton == null) {
+            jShowHomepageButton = new JButton();
+            jShowHomepageButton.setText("Show");
+            jShowHomepageButton.setPreferredSize(new java.awt.Dimension(40,18));
+            jShowHomepageButton.setMargin(new java.awt.Insets(2,2,2,2));
+            jShowHomepageButton.setFont(new java.awt.Font("Dialog", java.awt.Font.BOLD, 10));
+            jShowHomepageButton.addActionListener(new java.awt.event.ActionListener() {
+                public void actionPerformed(java.awt.event.ActionEvent e) {
+                    AdminTool.showHomepage(getJHomepageTextField().getText(),
+                        DetailsDialog.this);
+                }
+            });
+        }
+        return jShowHomepageButton;
+    }
+
+}  //  @jve:decl-index=0:visual-constraint="10,10"

+ 307 - 0
jplag.adminTool/src/main/java/jplagAdminTool/LoginDialog.java

@@ -0,0 +1,307 @@
+/*
+ * Created on 08.06.2005
+ * Author: Moritz Kroll
+ */
+
+package jplagAdminTool;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionListener;
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+import javax.jnlp.BasicService;
+import javax.jnlp.FileContents;
+import javax.jnlp.PersistenceService;
+import javax.jnlp.ServiceManager;
+import javax.jnlp.UnavailableServiceException;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JProgressBar;
+import javax.swing.JTextField;
+
+public class LoginDialog extends JDialog {
+	private static final long serialVersionUID = -5951691564111605981L;
+	private javax.swing.JPanel jContentPane = null;
+	private JPanel jPanel = null;
+	private JLabel jLabel = null;
+	private JTextField jUsernameField = null;
+	private JLabel jLabel1 = null;
+	private JPasswordField jPasswordField = null;
+	private JPanel jPanel1 = null;
+	private JButton jOKButton = null;
+	private JButton jCancelButton = null;
+	
+	private AdminTool adminTool = null;
+	private JProgressBar jProgressBar = null;
+	/**
+	 * This is the default constructor
+	 */
+	public LoginDialog(JFrame parent) {
+		super(parent);
+		initialize();
+
+		if (getJUsernameField().getText().length() > 0)
+			getJPasswordField().requestFocus();
+	}
+
+	/**
+	 * This method initializes this
+	 * 
+	 * @return void
+	 */
+	private void initialize() {
+		this.setSize(231, 131);
+        this.setResizable(false);
+		this.setTitle("Login dialog...");
+		this.setContentPane(getJContentPane());
+	}
+	
+	/**
+	 * This method initializes jContentPane
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	private javax.swing.JPanel getJContentPane() {
+		if(jContentPane == null) {
+			jContentPane = new javax.swing.JPanel();
+			jContentPane.setLayout(new java.awt.BorderLayout());
+			jContentPane.add(getJPanel1(), java.awt.BorderLayout.SOUTH);
+			jContentPane.add(getJPanel(), java.awt.BorderLayout.CENTER);
+		}
+		return jContentPane;
+	}
+
+	/**
+	 * This method initializes jPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */    
+	private JPanel getJPanel() {
+		if (jPanel == null) {
+			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
+			gridBagConstraints4.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints4.insets = new java.awt.Insets(3,3,1,0);
+			gridBagConstraints4.gridx = 1;
+			gridBagConstraints4.gridy = 1;
+			gridBagConstraints4.ipadx = 100;
+			gridBagConstraints4.ipady = 6;
+			gridBagConstraints4.weightx = 1.0;
+			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
+			gridBagConstraints3.insets = new java.awt.Insets(3,0,1,2);
+			gridBagConstraints3.gridx = 0;
+			gridBagConstraints3.gridy = 1;
+			gridBagConstraints3.anchor = java.awt.GridBagConstraints.WEST;
+			GridBagConstraints gridBagConstraints21 = new GridBagConstraints();
+			gridBagConstraints21.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints21.insets = new java.awt.Insets(0,3,2,0);
+			gridBagConstraints21.gridx = 1;
+			gridBagConstraints21.gridy = 0;
+			gridBagConstraints21.ipadx = 100;
+			gridBagConstraints21.ipady = 6;
+			gridBagConstraints21.weightx = 1.0;
+			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
+			gridBagConstraints11.insets = new java.awt.Insets(0,0,2,2);
+			gridBagConstraints11.gridx = 0;
+			gridBagConstraints11.gridy = 0;
+			gridBagConstraints11.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel1 = new JLabel();
+			jLabel1.setText("Password:");
+			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
+			gridBagConstraints2.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints2.gridx = 1;
+			gridBagConstraints2.gridy = 0;
+			gridBagConstraints2.weightx = 1.0;
+			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
+			gridBagConstraints1.gridx = 0;
+			gridBagConstraints1.gridy = 0;
+			jLabel = new JLabel();
+			jLabel.setText("Username:");
+			jPanel = new JPanel();
+			jPanel.setLayout(new GridBagLayout());
+			jPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+			jPanel.add(getJPasswordField(), gridBagConstraints4);
+			jPanel.add(jLabel1, gridBagConstraints3);
+			jPanel.add(getJUsernameField(), gridBagConstraints21);
+			jPanel.add(jLabel, gridBagConstraints11);
+		}
+		return jPanel;
+	}
+	
+	private String readUsername() {
+		String str="";
+		try {
+			PersistenceService ps = (PersistenceService) ServiceManager.
+				lookup("javax.jnlp.PersistenceService");
+			BasicService bs = (BasicService) ServiceManager.
+				lookup("javax.jnlp.BasicService");
+			URL baseURL = bs.getCodeBase();
+			URL admintoolURL = new URL(baseURL,"AdminTool.cfg");
+			FileContents fc = ps.get(admintoolURL);
+			BufferedReader reader = new BufferedReader(
+					new InputStreamReader(fc.getInputStream()));
+			str=reader.readLine();
+			reader.close();
+		}
+		// if an exception is thrown, the username just can't be set
+		catch(UnavailableServiceException e) {}
+		catch(Exception e) {}
+		
+		return str;
+	}
+	
+	private void storeUsername()
+	{
+		try {
+			PersistenceService ps = (PersistenceService) ServiceManager.
+				lookup("javax.jnlp.PersistenceService");
+			BasicService bs = (BasicService) ServiceManager.
+				lookup("javax.jnlp.BasicService");
+			URL baseURL = bs.getCodeBase();
+			URL admintoolURL = new URL(baseURL,"AdminTool.cfg");
+			
+			// delete file if already exists
+			try { ps.delete(admintoolURL); } catch(Exception e) {}
+			ps.create(admintoolURL,1024);
+			FileContents fc=ps.get(admintoolURL);
+			DataOutputStream os=new DataOutputStream(fc.getOutputStream(true));
+			os.writeBytes(getJUsernameField().getText() + "\n");
+			os.flush();
+			os.close();
+		}
+		// if an exception is thrown, the username just can't be stored
+		catch(UnavailableServiceException e) {}
+		catch(Exception e) {}
+	}
+
+	/**
+	 * This method initializes jTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJUsernameField() {
+		if (jUsernameField == null) {
+			jUsernameField = new JTextField();
+			jUsernameField.setText(readUsername());
+		}
+		return jUsernameField;
+	}
+
+	/**
+	 * This method initializes jPasswordField	
+	 * 	
+	 * @return javax.swing.JPasswordField	
+	 */    
+	private JPasswordField getJPasswordField() {
+		if (jPasswordField == null) {
+			jPasswordField = new JPasswordField();
+		}
+		return jPasswordField;
+	}
+
+	/**
+	 * This method initializes jPanel1	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */    
+	private JPanel getJPanel1() {
+		if (jPanel1 == null) {
+			jPanel1 = new JPanel();
+			jPanel1.add(getJOKButton(), null);
+			jPanel1.add(getJProgressBar(), null);
+			jPanel1.add(getJCancelButton(), null);
+		}
+		return jPanel1;
+	}
+
+	/**
+	 * This method initializes jButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJOKButton() {
+		if (jOKButton == null) {
+			jOKButton = new JButton();
+			jOKButton.setText("OK");
+			jOKButton.setPreferredSize(new java.awt.Dimension(70,26));
+			jOKButton.setMargin(new java.awt.Insets(2,10,2,10));
+			jOKButton.addActionListener(new ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					final SwingWorker worker = new SwingWorker() {
+						public Object construct() {
+							if(adminTool==null)
+							{
+								adminTool=new AdminTool();
+								adminTool.setDefaultCloseOperation(
+                                    JFrame.EXIT_ON_CLOSE);
+							}
+							if(adminTool.setLogin(getJUsernameField().getText(),
+									new String(
+                                        getJPasswordField().getPassword()),
+                                    LoginDialog.this))
+							{		
+								storeUsername();
+								setVisible(false);
+								adminTool.setLocationRelativeTo(null);
+								adminTool.setVisible(true);
+								getOwner().dispose();
+							}
+							
+							return null;
+						}
+						
+						public void finished() {
+							getJProgressBar().setIndeterminate(false);
+						}
+					};
+					getJProgressBar().setIndeterminate(true);
+					worker.start();
+				}
+			});
+			getRootPane().setDefaultButton(jOKButton);
+		}
+		return jOKButton;
+	}
+
+	/**
+	 * This method initializes jButton1	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJCancelButton() {
+		if (jCancelButton == null) {
+			jCancelButton = new JButton();
+			jCancelButton.setText("Cancel");
+			jCancelButton.setPreferredSize(new java.awt.Dimension(70,26));
+			jCancelButton.setMargin(new java.awt.Insets(2,10,2,10));
+			jCancelButton.addActionListener(new ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {    
+					System.exit(0);
+				}
+			});
+		}
+		return jCancelButton;
+	}
+
+	/**
+	 * This method initializes jProgressBar	
+	 * 	
+	 * @return javax.swing.JProgressBar	
+	 */    
+	private JProgressBar getJProgressBar() {
+		if (jProgressBar == null) {
+			jProgressBar = new JProgressBar();
+			jProgressBar.setPreferredSize(new java.awt.Dimension(60,14));
+		}
+		return jProgressBar;
+	}
+
+}  //  @jve:decl-index=0:visual-constraint="10,10"

+ 804 - 0
jplag.adminTool/src/main/java/jplagAdminTool/MailDialog.java

@@ -0,0 +1,804 @@
+/*
+ * Created on 12.06.2005
+ * Author: Moritz Kroll
+ */
+
+package jplagAdminTool;
+
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.util.Vector;
+
+import javax.swing.AbstractAction;
+import javax.swing.Box;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JRootPane;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.KeyStroke;
+import javax.swing.Timer;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.BadLocationException;
+
+import jplagWsClient.jplagClient.MailTemplate;
+import jplagWsClient.jplagClient.RequestData;
+import jplagWsClient.jplagClient.SetMailTemplateParams;
+
+public class MailDialog extends JDialog {
+	private static final long serialVersionUID = -384670645825122963L;
+
+	public static final String JPLAG_SERVER = "https://www.ipd.kit.edu/jplag";
+
+	public static final int MAIL_ACCEPTED = 0;
+	public static final int MAIL_DECLINED = 1;
+	public static final int MAIL_SERVER = 2;
+    public static final int MAIL_ALL = 3;
+	
+	public static final int USERNAME=0;
+	public static final int PASSWORD=1;
+	public static final int EXPIRES=2;
+	public static final int REALNAME=3;
+	public static final int EMAIL=4;
+	public static final int EMAILSECOND=5;
+	public static final int HOMEPAGE=6;
+	public static final int SERVER=7;
+	
+	private static final String[] tagNames = { "username", "password", "expires", "realname", "email", "emailSecond", "homepage", "server" };
+
+	/*
+	 * public static final int S_USERNAME=0; public static final int
+	 * S_PASSWORD=1; public static final int S_EXPIRES=2; public static final
+	 * int S_LASTUSAGE=3; public static final int S_NUMOFSUBS=4; public static
+	 * final int S_REALNAME=5; public static final int S_EMAIL=6; public static
+	 * final int S_EMAILSECOND=7; public static final int S_HOMEPAGE=8; public
+	 * static final int S_SERVER=9;
+	 * 
+	 * private static final String[] serverTagNames = { "username", "password",
+	 * "expires", "lastUsage", "numOfSubs", "realname", "email", "emailSecond",
+	 * "homepage", "server" };
+	 */
+    
+	private static final String[] typeNames = { "accepted", "declined", "serverMail" };
+	
+	private javax.swing.JPanel jContentPane = null;
+	private JTextArea jTemplateTextArea = null;
+	private JPanel jPanel = null;
+	private JLabel jLabel = null;
+	private JLabel jLabel1 = null;
+	private JScrollPane jTemplateScrollPane = null;
+	private JScrollPane jPreviewScrollPane = null;
+	private JTextArea jPreviewTextArea = null;
+	private JPanel jButtonPanel = null;
+	private JButton jSaveAndSendButton = null;
+	private JButton jSendButton = null;
+	private JButton jCancelButton = null;
+	private JButton jSaveButton = null;
+	private JComboBox<String> jTemplateComboBox = null;
+	private JLabel jLabel2 = null;
+	private JComboBox<String> jTagComboBox = null;
+	
+    private Vector<MailTemplate> templates = null;
+	private AdminTool adminTool = null;
+	private int type = 0;
+	private RequestData reqData = null;
+    private boolean showSendButtons = true;
+	
+	private boolean cancelled = true;
+	private String preview = "";
+	private String subject = "";
+	private JTextField jSubjectField = null;
+	private JLabel jLabel3 = null;
+    private JPanel jTypeChoosePanel = null;
+    private JLabel jChooseTypeLabel = null;
+    private JComboBox<String> jTypeComboBox = null;
+    private JButton jCopyTemplateButton = null;
+    private JButton jRenameTemplateButton = null;
+    private JButton jDeleteTemplateButton = null;
+	
+	public MailDialog(int typ, String title, RequestData rd, JDialog parent,
+			AdminTool at) {
+		super(parent,true);		 // make modal
+        init(typ,title,rd,at);
+    }
+        
+	public MailDialog(int typ, String title, RequestData rd, AdminTool at) {
+		super(at,true);		     // make modal
+        init(typ,title,rd,at);
+	}
+	
+    private void init(int typ, String title, RequestData rd, AdminTool at) {
+        adminTool = at;
+        type = typ;
+        reqData = rd;
+        if(type == MAIL_ALL) {
+            showSendButtons = false;
+            type = MAIL_ACCEPTED;
+        }
+        try {
+            MailTemplate[] temps = at.getJPlagStub().getMailTemplates(type).
+                    getItems();
+            templates = new Vector<MailTemplate>(temps.length,3);
+            for(int i=0;i<temps.length;i++)
+                templates.add(temps[i]);
+        }
+        catch(Exception ex) {
+            at.CheckException(ex,at);
+        }
+        initialize(title);
+    }
+
+    protected JRootPane createRootPane() {
+		KeyStroke stroke=KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
+		JRootPane rootPane=new JRootPane();
+		rootPane.registerKeyboardAction(new ActionListener() {
+				public void actionPerformed(ActionEvent actionEvent) {
+					setVisible(false);
+                    dispose();
+				}
+			}, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
+		
+		return rootPane;
+	}
+
+	public boolean isCancelled() {
+		return cancelled;
+	}
+	
+	public String getMailString() {
+		return preview;
+	}
+	
+	public String getMailSubjectString() {
+		return subject;
+	}
+
+	/**
+	 * This method initializes this
+	 * 
+	 * @return void
+	 */
+	private void initialize(String title) {
+		this.setSize(640, 400);
+		this.setTitle(title);
+		this.setContentPane(getJContentPane());
+	}
+
+	/**
+	 * This method initializes jContentPane
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	private javax.swing.JPanel getJContentPane() {
+		if(jContentPane == null) {
+			jContentPane = new javax.swing.JPanel();
+			jContentPane.setLayout(new java.awt.BorderLayout());
+			jContentPane.add(getJPanel(), java.awt.BorderLayout.CENTER);
+            jContentPane.add(getJButtonPanel(), java.awt.BorderLayout.SOUTH);
+            if(!showSendButtons)
+                jContentPane.add(getJTypeChoosePanel(),
+                    java.awt.BorderLayout.NORTH);
+		}
+		return jContentPane;
+	}
+
+	/**
+	 * This method initializes jPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */    
+	private JPanel getJPanel() {
+		if (jPanel == null) {
+			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
+			gridBagConstraints10.gridx = 4;
+			gridBagConstraints10.insets = new java.awt.Insets(0,5,0,0);
+			gridBagConstraints10.gridy = 0;
+			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
+			gridBagConstraints1.gridx = 3;
+			gridBagConstraints1.insets = new java.awt.Insets(0,5,0,0);
+			gridBagConstraints1.gridy = 0;
+			GridBagConstraints gridBagConstraints = new GridBagConstraints();
+			gridBagConstraints.gridx = 2;
+			gridBagConstraints.insets = new java.awt.Insets(0,5,0,0);
+			gridBagConstraints.gridy = 0;
+			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
+			gridBagConstraints6.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints6.gridx = 1;
+			gridBagConstraints6.gridy = 1;
+			gridBagConstraints6.gridwidth = 1;
+			gridBagConstraints6.weightx = 1.0D;
+			gridBagConstraints6.insets = new java.awt.Insets(10,5,0,5);
+			GridBagConstraints gridBagConstraints51 = new GridBagConstraints();
+			gridBagConstraints51.gridx = 0;
+			gridBagConstraints51.gridy = 1;
+			gridBagConstraints51.insets = new java.awt.Insets(10,0,0,0);
+			gridBagConstraints51.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel3 = new JLabel();
+			jLabel3.setText("Subject:");
+			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
+			gridBagConstraints9.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints9.gridx = 3;
+			gridBagConstraints9.gridy = 1;
+			gridBagConstraints9.gridwidth = 2;
+			gridBagConstraints9.insets = new java.awt.Insets(5,5,0,0);
+			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
+			gridBagConstraints8.gridx = 2;
+			gridBagConstraints8.insets = new java.awt.Insets(10,0,0,0);
+			gridBagConstraints8.gridy = 1;
+			jLabel2 = new JLabel();
+			jLabel2.setText("Insert tag:");
+			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
+			gridBagConstraints7.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints7.gridx = 1;
+			gridBagConstraints7.gridy = 0;
+			gridBagConstraints7.weightx = 1.0;
+			gridBagConstraints7.insets = new java.awt.Insets(0,5,0,5);
+			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
+			gridBagConstraints5.fill = java.awt.GridBagConstraints.BOTH;
+			gridBagConstraints5.gridx = 0;
+			gridBagConstraints5.gridy = 4;
+			gridBagConstraints5.weightx = 1.0;
+			gridBagConstraints5.weighty = 1.0;
+			gridBagConstraints5.insets = new java.awt.Insets(5,10,0,0);
+			gridBagConstraints5.gridwidth = 6;
+			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
+			gridBagConstraints4.fill = java.awt.GridBagConstraints.BOTH;
+			gridBagConstraints4.gridx = 0;
+			gridBagConstraints4.gridy = 2;
+			gridBagConstraints4.weightx = 1.0;
+			gridBagConstraints4.weighty = 1.0;
+			gridBagConstraints4.insets = new java.awt.Insets(5,10,5,0);
+			gridBagConstraints4.gridwidth = 5;
+			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
+			gridBagConstraints3.gridx = 0;
+			gridBagConstraints3.gridy = 3;
+			gridBagConstraints3.anchor = java.awt.GridBagConstraints.WEST;
+			gridBagConstraints3.gridwidth = 4;
+			jLabel1 = new JLabel();
+			jLabel1.setText("E-Mail preview:");
+			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
+			gridBagConstraints2.gridx = 0;
+			gridBagConstraints2.gridy = 0;
+			gridBagConstraints2.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel = new JLabel();
+			jLabel.setText("Template:");
+			jPanel = new JPanel();
+			jPanel.setLayout(new GridBagLayout());
+			jPanel.setBorder(
+                javax.swing.BorderFactory.createEmptyBorder(5,5,5,5));
+			jPanel.add(getJPreviewScrollPane(), gridBagConstraints5);
+			jPanel.add(getJSubjectField(), gridBagConstraints6);
+			jPanel.add(jLabel3, gridBagConstraints51);
+			jPanel.add(getJTagComboBox(), gridBagConstraints9);
+			jPanel.add(jLabel2, gridBagConstraints8);
+			jPanel.add(getJTemplateComboBox(), gridBagConstraints7);
+			jPanel.add(jLabel, gridBagConstraints2);
+			jPanel.add(jLabel1, gridBagConstraints3);
+			jPanel.add(getJTemplateScrollPane(), gridBagConstraints4);
+			jPanel.add(getJCopyTemplateButton(), gridBagConstraints);
+			jPanel.add(getJRenameTemplateButton(), gridBagConstraints1);
+			jPanel.add(getJDeleteTemplateButton(), gridBagConstraints10);
+		}
+		return jPanel;
+	}
+
+	/**
+	 * This method initializes jTemplateScrollPane	
+	 * 	
+	 * @return javax.swing.JScrollPane	
+	 */    
+	private JScrollPane getJTemplateScrollPane() {
+		if (jTemplateScrollPane == null) {
+			jTemplateScrollPane = new JScrollPane();
+			jTemplateScrollPane.setViewportView(getJTemplateTextArea());
+		}
+		return jTemplateScrollPane;
+	}
+
+    /**
+     * This method initializes jTextArea    
+     *  
+     * @return javax.swing.JTextArea    
+     */    
+	private JTextArea getJTemplateTextArea() {
+		if (jTemplateTextArea == null) {
+			jTemplateTextArea = new JTextArea();
+			jTemplateTextArea.setLineWrap(true);
+			jTemplateTextArea.setWrapStyleWord(true);
+			jTemplateTextArea.getDocument().addDocumentListener(new DocumentListener() {
+				private Timer timer = null;
+
+				@SuppressWarnings("serial")
+				private Timer getTimer() {
+					if (timer == null) {
+						timer = new Timer(300, new AbstractAction() {
+							public void actionPerformed(ActionEvent e) {
+								updatePreview();
+							}
+						});
+						timer.setRepeats(false);
+					}
+					return timer;
+				}
+
+				public void changedUpdate(DocumentEvent arg0) {
+					getTimer().restart();
+				}
+
+				public void insertUpdate(DocumentEvent arg0) {
+					getTimer().restart();
+				}
+
+				public void removeUpdate(DocumentEvent arg0) {
+					getTimer().restart();
+				}
+
+			});
+		}
+		return jTemplateTextArea;
+    }
+    
+	/**
+	 * This method initializes jPreviewScrollPane	
+	 * 	
+	 * @return javax.swing.JScrollPane	
+	 */    
+	private JScrollPane getJPreviewScrollPane() {
+		if (jPreviewScrollPane == null) {
+			jPreviewScrollPane = new JScrollPane();
+			jPreviewScrollPane.setViewportView(getJPreviewTextArea());
+		}
+		return jPreviewScrollPane;
+	}
+
+	/**
+	 * This method initializes jPreviewTextArea	
+	 * 	
+	 * @return javax.swing.JTextArea	
+	 */    
+	private JTextArea getJPreviewTextArea() {
+		if (jPreviewTextArea == null) {
+			jPreviewTextArea = new JTextArea();
+            jPreviewTextArea.setLineWrap(true);
+            jPreviewTextArea.setWrapStyleWord(true);
+			jPreviewTextArea.setEditable(false);
+		}
+		return jPreviewTextArea;
+	}
+
+	/**
+	 * This method initializes jButtonPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */    
+	private JPanel getJButtonPanel() {
+		if (jButtonPanel == null) {
+			jButtonPanel = new JPanel();
+            if(showSendButtons)
+            {
+                jButtonPanel.add(getJSendButton(), null);
+                jButtonPanel.add(getJCancelButton(), null);
+                jButtonPanel.add(Box.createHorizontalStrut(20),null);
+                jButtonPanel.add(getJSaveButton(), null);
+				jButtonPanel.add(getJSaveAndSendButton(), null);
+            }
+            else {
+                jButtonPanel.add(getJSaveButton(), null);
+                jButtonPanel.add(getJCancelButton(), null);
+            }
+		}
+		return jButtonPanel;
+	}
+
+	/**
+	 * This method initializes jButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJSaveAndSendButton() {
+		if (jSaveAndSendButton == null) {
+			jSaveAndSendButton = new JButton();
+			jSaveAndSendButton.setText("Save and send");
+			jSaveAndSendButton.addActionListener(
+                new java.awt.event.ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {    
+					subject=getJSubjectField().getText();
+					saveTemplate();
+					cancelled = false;
+					setVisible(false);
+                    dispose();
+				}
+			});
+		}
+		return jSaveAndSendButton;
+	}
+
+	/**
+	 * This method initializes jButton2	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJSendButton() {
+		if (jSendButton == null) {
+			jSendButton = new JButton();
+			jSendButton.setText("Send");
+			jSendButton.addActionListener(new java.awt.event.ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					subject=getJSubjectField().getText();
+					cancelled = false;
+					setVisible(false);
+                    dispose();
+				}
+			});
+		}
+		return jSendButton;
+	}
+
+	/**
+	 * This method initializes jButton1	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJCancelButton() {
+		if (jCancelButton == null) {
+			jCancelButton = new JButton();
+			jCancelButton.setText(showSendButtons ? "Cancel" : "Close");
+			jCancelButton.addActionListener(
+                new java.awt.event.ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {    
+					setVisible(false);
+                    dispose();
+				}
+			});
+		}
+		return jCancelButton;
+	}
+	
+    private void setMailTemplate(String name, String subject, String data) {
+        try {
+            adminTool.getJPlagStub().setMailTemplate(new SetMailTemplateParams(
+                    type,new MailTemplate(name,subject,data)));
+        }
+        catch(Exception ex) {
+            adminTool.CheckException(ex,this);
+        }
+    }
+    
+	private void saveTemplate() {
+        String name = (String) getJTemplateComboBox().getSelectedItem();
+        String data = getJTemplateTextArea().getText();
+        setMailTemplate(name, subject, data);
+
+        // Update template object
+        
+        int tempNum = jTemplateComboBox.getSelectedIndex();
+        if(tempNum < 0)     // if no name selected don't update...
+            return;         // (this shouldn't happen...)
+        
+        MailTemplate tmpl = templates.get(tempNum);
+        tmpl.setName(name);
+        tmpl.setSubject(subject);
+        tmpl.setData(data);
+    }
+
+	/**
+	 * This method initializes jButton3	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJSaveButton() {
+		if (jSaveButton == null) {
+			jSaveButton = new JButton();
+			jSaveButton.setText("Save");
+			jSaveButton.addActionListener(new java.awt.event.ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {    
+					subject=getJSubjectField().getText();
+					saveTemplate();
+                }
+			});
+		}
+		return jSaveButton;
+	}
+	
+	private void updatePreview() {
+		String template = getJTemplateTextArea().getText();
+		String[] tokens = template.split("[{}]");
+		// TODO: Check whether every '{' has a following '}'
+		preview = tokens[0];
+		for(int i=1;i<tokens.length;i+=2)
+		{
+			int j;
+			for(j=0;j<tagNames.length;j++)
+			{
+				if(tagNames[j].equals(tokens[i]))
+					break;
+			}
+			switch(j)
+			{
+				case USERNAME: preview += reqData.getUsername(); break;
+				case PASSWORD: preview += reqData.getPassword(); break;
+				case REALNAME: preview += reqData.getRealName(); break;
+				case EMAIL: preview += reqData.getEmail(); break;
+				case EMAILSECOND: preview += reqData.getEmailSecond(); break;
+				case HOMEPAGE: preview += reqData.getHomepage(); break;
+				case SERVER: preview += JPLAG_SERVER; break;
+				default: preview += "[N/A]"; break;
+			}
+			if(i+1<tokens.length) preview += tokens[i+1];
+		}
+		getJPreviewTextArea().setText(preview);
+		try
+		{
+			// Set preview cursor into the same line as the template cursor  
+			int viewline=getJTemplateTextArea().getLineOfOffset(
+					getJTemplateTextArea().getCaretPosition());
+			getJPreviewTextArea().setCaretPosition(
+					getJPreviewTextArea().getLineStartOffset(viewline));
+			
+			// Let preview viewport start painting at the same line as
+			// the template viewport
+			Point p=getJTemplateScrollPane().getViewport().getViewPosition();
+			getJPreviewScrollPane().getViewport().setViewPosition(p);
+		}
+		catch(BadLocationException ex) {}	// just don't scroll
+	}
+
+	/**
+	 * This method initializes jComboBox	
+	 * 	
+	 * @return javax.swing.JComboBox	
+	 */    
+	private JComboBox<String> getJTemplateComboBox() {
+		if (jTemplateComboBox == null) {
+			String[] templateNames = new String[templates.size()];
+			for(int i=0;i<templates.size();i++)
+				templateNames[i] = templates.get(i).getName();
+			jTemplateComboBox = new JComboBox<String>(templateNames);
+			jTemplateComboBox.addActionListener(
+                new java.awt.event.ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {    
+					int tempNum = jTemplateComboBox.getSelectedIndex();
+					if(tempNum < 0)		// if new name selected
+						return;			// don't change the text
+                    MailTemplate tmpl = templates.get(tempNum);
+					getJSubjectField().setText(tmpl.getSubject());
+					getJTemplateTextArea().setText(tmpl.getData());
+					getJTemplateTextArea().setCaretPosition(0);
+					updatePreview();
+				}
+			});
+			if(templates.size()>0)
+				jTemplateComboBox.setSelectedIndex(0);
+		}
+		return jTemplateComboBox;
+	}
+
+	/**
+	 * This method initializes jComboBox1	
+	 * 	
+	 * @return javax.swing.JComboBox	
+	 */    
+	private JComboBox<String> getJTagComboBox() {
+		if (jTagComboBox == null) {
+			jTagComboBox = new JComboBox<String>(tagNames);
+			jTagComboBox.addActionListener(new java.awt.event.ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					JTextArea ta = getJTemplateTextArea();
+					ta.insert("{" + (String) jTagComboBox.getSelectedItem() +
+							"}",ta.getCaretPosition());
+				}
+			});
+		}
+		return jTagComboBox;
+	}
+
+	/**
+	 * This method initializes jTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJSubjectField() {
+		if (jSubjectField == null) {
+			jSubjectField = new JTextField();
+			jSubjectField.setColumns(51);
+		}
+		return jSubjectField;
+	}
+
+    /**
+     * This method initializes jTypeChoosePanel	
+     * 	
+     * @return javax.swing.JPanel	
+     */
+    private JPanel getJTypeChoosePanel() {
+        if(jTypeChoosePanel == null) {
+            FlowLayout flowLayout = new FlowLayout();
+            flowLayout.setAlignment(java.awt.FlowLayout.LEFT);
+            flowLayout.setVgap(0);
+            jChooseTypeLabel = new JLabel();
+            jChooseTypeLabel.setText("Type:");
+            jChooseTypeLabel.setPreferredSize(jLabel.getPreferredSize());
+            jTypeChoosePanel = new JPanel();
+            jTypeChoosePanel.setBorder(
+                javax.swing.BorderFactory.createEmptyBorder(5,0,0,0));
+            jTypeChoosePanel.setLayout(flowLayout);
+            jTypeChoosePanel.add(jChooseTypeLabel, null);
+            jTypeChoosePanel.add(getJTypeComboBox(), null);
+        }
+        return jTypeChoosePanel;
+    }
+    
+    private void setButtonsEnabled(boolean enabled) {
+        if(showSendButtons) {
+            getJSendButton().setEnabled(enabled);
+            getJSaveAndSendButton().setEnabled(enabled);
+        }
+        getJSaveButton().setEnabled(enabled);
+    }
+
+    /**
+     * This method initializes jTypeComboBox	
+     * 	
+     * @return javax.swing.JComboBox	
+     */
+    private JComboBox<String> getJTypeComboBox() {
+        if(jTypeComboBox == null) {
+			jTypeComboBox = new JComboBox<String>(typeNames);
+            jTypeComboBox.addActionListener(
+                new java.awt.event.ActionListener() {
+                public void actionPerformed(java.awt.event.ActionEvent e) {
+                    final SwingWorker worker = new SwingWorker() {
+                        public Object construct() {
+                            try {
+                                MailTemplate[] temps = adminTool.getJPlagStub().
+                                    getMailTemplates(type).getItems();
+                                templates =
+                                    new Vector<MailTemplate>(temps.length,3);
+                                for(int i=0;i<temps.length;i++)
+                                    templates.add(temps[i]);
+                            }
+                            catch(Exception ex)
+                            {
+                                adminTool.CheckException(ex,adminTool);
+                            }
+                            return null;
+                        }
+                        
+                        public void finished() {
+                            jTemplateComboBox.removeAllItems();
+                            for(int i=0;i<templates.size();i++)
+                                jTemplateComboBox.addItem(
+                                    templates.get(i).getName());
+
+                            if(templates.size()>0)
+                                jTemplateComboBox.setSelectedIndex(0);
+                            
+                            setButtonsEnabled(true);
+                        }
+                    };
+                    int newtype = jTypeComboBox.getSelectedIndex();
+                    if(newtype == type) return;
+                    setButtonsEnabled(false);
+                    type = newtype;
+                    worker.start();
+                }
+            });
+        }
+        return jTypeComboBox;
+    }
+
+    /**
+     * This method initializes jCopyTemplateButton	
+     * 	
+     * @return javax.swing.JButton	
+     */
+    private JButton getJCopyTemplateButton() {
+        if(jCopyTemplateButton == null) {
+            jCopyTemplateButton = new JButton();
+            jCopyTemplateButton.setText("Copy");
+            jCopyTemplateButton.addActionListener(
+                new java.awt.event.ActionListener() {
+                public void actionPerformed(java.awt.event.ActionEvent e) {
+                    String newname = JOptionPane.showInputDialog(
+                        MailDialog.this, "Please enter the new template name" +
+                        "\n(You will have to save the new template before\n" +
+                        "switching to another one to avoid loosing the text):",
+                        "Add new template", JOptionPane.PLAIN_MESSAGE);
+                    if(newname.length()==0) {
+                        JOptionPane.showMessageDialog(MailDialog.this,
+                            "You didn't provide a new template name!",
+                            "Adding new template aborted",
+                            JOptionPane.WARNING_MESSAGE);
+                        return;
+                    }
+                    MailTemplate newtemp = new MailTemplate(newname,
+                        getJSubjectField().getText(),
+                        getJTemplateTextArea().getText());
+                    templates.add(newtemp);
+                    getJTemplateComboBox().addItem(newname);
+                    getJTemplateComboBox().setSelectedItem(newname);
+                }
+            });
+        }
+        return jCopyTemplateButton;
+    }
+
+    /**
+     * This method initializes jRenameTemplateButton	
+     * 	
+     * @return javax.swing.JButton	
+     */
+    private JButton getJRenameTemplateButton() {
+        if(jRenameTemplateButton == null) {
+            jRenameTemplateButton = new JButton();
+            jRenameTemplateButton.setText("Rename");
+            jRenameTemplateButton.addActionListener(
+                new java.awt.event.ActionListener() {
+                public void actionPerformed(java.awt.event.ActionEvent e) {
+                    int tempNum = jTemplateComboBox.getSelectedIndex();
+                    if(tempNum < 0)     // if no name selected
+                        return;         // don't rename
+                    MailTemplate tmpl = templates.get(tempNum);
+                    
+                    String newname = JOptionPane.showInputDialog(
+                        MailDialog.this, "The old template name is:\n     "
+                            + tmpl.getName() + "\nPlease enter the new "
+                            + "template name:",
+                        "Rename template", JOptionPane.PLAIN_MESSAGE);
+
+                    setMailTemplate(tmpl.getName(),newname,"");
+                    tmpl.setName(newname);
+                    jTemplateComboBox.removeItemAt(tempNum);
+                    jTemplateComboBox.insertItemAt(newname,tempNum);
+                    jTemplateComboBox.setSelectedItem(newname);
+                }
+            });
+        }
+        return jRenameTemplateButton;
+    }
+
+    /**
+     * This method initializes jDeleteTemplateButton	
+     * 	
+     * @return javax.swing.JButton	
+     */
+    private JButton getJDeleteTemplateButton() {
+        if(jDeleteTemplateButton == null) {
+            jDeleteTemplateButton = new JButton();
+            jDeleteTemplateButton.setText("Delete");
+            jDeleteTemplateButton.addActionListener(
+                new java.awt.event.ActionListener() {
+                public void actionPerformed(java.awt.event.ActionEvent e) {
+                    int tempNum = jTemplateComboBox.getSelectedIndex();
+                    if(tempNum < 0)     // if no name selected
+                        return;         // don't rename
+                    MailTemplate tmpl = templates.get(tempNum);
+                    
+                    if(JOptionPane.showConfirmDialog(MailDialog.this,
+                            "Do you really want to delete this template:\n     "
+                            + tmpl.getName() + "?", "Delete template",
+                            JOptionPane.YES_NO_OPTION,
+                            JOptionPane.WARNING_MESSAGE)==JOptionPane.NO_OPTION)
+                        return;
+                    
+                    setMailTemplate(tmpl.getName(),"","");
+                    jTemplateComboBox.removeItemAt(tempNum);
+                    templates.remove(tempNum);
+                }
+            });
+        }
+        return jDeleteTemplateButton;
+    }
+}  //  @jve:decl-index=0:visual-constraint="10,10"

+ 214 - 0
jplag.adminTool/src/main/java/jplagAdminTool/PassDialog.java

@@ -0,0 +1,214 @@
+package jplagAdminTool;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.KeyEvent;
+
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRootPane;
+import javax.swing.JTextField;
+import javax.swing.KeyStroke;
+
+public class PassDialog extends JDialog {
+	private static final long serialVersionUID = 1L;
+	private javax.swing.JPanel jContentPane = null;
+	private JTextField jOldPassTextField = null;
+	private JTextField jNewPassTextField = null;
+	private JButton jButton = null;
+	private JButton jButton1 = null;
+	private JLabel jLabel = null;
+	private JLabel jLabel1 = null;
+	private javax.swing.JPanel jPanel = null;
+	
+	private String oldpassword;
+	private BackedUserData data;
+	private AdminTool adminTool;
+	private JPanel jPanel1 = null;
+
+	/**
+	 * This is the default constructor
+	 */
+	public PassDialog(BackedUserData ud, AdminTool parent) {
+		super(parent,true);				 // make dialog modal
+		data=ud;
+		adminTool=parent;
+		oldpassword=data.getPassword();
+        if(oldpassword.length()==0) oldpassword="*********";
+		initialize();
+	}
+	
+	protected JRootPane createRootPane() {
+		KeyStroke stroke=KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
+		JRootPane rootPane=new JRootPane();
+		rootPane.registerKeyboardAction(new ActionListener() {
+				public void actionPerformed(ActionEvent actionEvent) {
+					setVisible(false);
+                    dispose();
+				}
+			}, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
+		
+		return rootPane;
+	}
+
+	/**
+	 * This method initializes this
+	 * 
+	 * @return void
+	 */
+	private void initialize() {
+		this.setSize(288, 133);
+		this.setTitle("Change password for user");
+		this.setContentPane(getJContentPane());
+	}
+	
+	/**
+	 * This method initializes jTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJOldPassTextField() {
+		if (jOldPassTextField == null) {
+			jOldPassTextField = new JTextField();
+			jOldPassTextField.setText(oldpassword);
+			jOldPassTextField.setEditable(false);
+			jOldPassTextField.setPreferredSize(new java.awt.Dimension(120,20));
+			jOldPassTextField.addFocusListener(new FocusListener() {
+				public void focusGained(FocusEvent e) {
+					jOldPassTextField.transferFocus();
+				}
+				public void focusLost(FocusEvent e) {
+					jOldPassTextField.removeFocusListener(this);
+				}});
+		}
+		return jOldPassTextField;
+	}
+
+	/**
+	 * This method initializes jTextField1	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJNewPassTextField() {
+		if (jNewPassTextField == null) {
+			jNewPassTextField = new JTextField();
+		}
+		return jNewPassTextField;
+	}
+
+	/**
+	 * This method initializes jButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJButton() {
+		if (jButton == null) {
+			jButton = new JButton();
+			jButton.setText("Apply");
+			jButton.addActionListener(new java.awt.event.ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					data.setPassword(getJNewPassTextField().getText());
+					if(adminTool.userDataChanged(data)) {
+						setVisible(false);
+                        dispose();
+                    }
+				}
+			});
+			getRootPane().setDefaultButton(jButton);
+		}
+		return jButton;
+	}
+
+	/**
+	 * This method initializes jButton1	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJButton1() {
+		if (jButton1 == null) {
+			jButton1 = new JButton();
+			jButton1.setText("Cancel");
+			jButton1.addActionListener(new java.awt.event.ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {    
+					setVisible(false);
+                    dispose();
+				}
+			});
+		}
+		return jButton1;
+	}
+
+	/**
+	 * This method initializes jContentPane
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	private javax.swing.JPanel getJContentPane() {
+		if(jContentPane == null) {
+			jContentPane = new javax.swing.JPanel();
+			jContentPane.setLayout(new java.awt.BorderLayout());
+			jContentPane.add(getJPanel1(), java.awt.BorderLayout.SOUTH);
+			jContentPane.add(getJPanel(), java.awt.BorderLayout.CENTER);
+		}
+		return jContentPane;
+	}
+	
+	private JPanel getJPanel() {
+		if(jPanel == null) {
+			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
+			gridBagConstraints8.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints8.gridx = 1;
+			gridBagConstraints8.gridy = 1;
+			gridBagConstraints8.weightx = 1.0D;
+			gridBagConstraints8.insets = new java.awt.Insets(3,3,1,0);
+			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
+			gridBagConstraints7.gridx = 0;
+			gridBagConstraints7.gridy = 1;
+			gridBagConstraints7.anchor = java.awt.GridBagConstraints.WEST;
+			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
+			gridBagConstraints6.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints6.gridx = 1;
+			gridBagConstraints6.gridy = 0;
+			gridBagConstraints6.weightx = 1.0D;
+			gridBagConstraints6.insets = new java.awt.Insets(0,3,2,0);
+			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
+			gridBagConstraints5.gridx = 0;
+			gridBagConstraints5.gridy = 0;
+			gridBagConstraints5.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel1 = new JLabel();
+			jLabel1.setText("New password:");
+			jLabel = new JLabel();
+			jLabel.setText("Old password:");
+			jPanel = new javax.swing.JPanel();
+			jPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(5,5,5,5));
+			jPanel.setLayout(new GridBagLayout());
+			jPanel.add(getJNewPassTextField(), gridBagConstraints8);
+			jPanel.add(jLabel1, gridBagConstraints7);
+			jPanel.add(getJOldPassTextField(), gridBagConstraints6);
+			jPanel.add(jLabel, gridBagConstraints5);
+		}
+		return jPanel;
+	}
+
+	/**
+	 * This method initializes jPanel1	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */    
+	private JPanel getJPanel1() {
+		if (jPanel1 == null) {
+			jPanel1 = new JPanel();
+			jPanel1.add(getJButton(), null);
+			jPanel1.add(getJButton1(), null);
+		}
+		return jPanel1;
+	}
+
+}  //  @jve:decl-index=0:visual-constraint="10,10"

+ 1101 - 0
jplag.adminTool/src/main/java/jplagAdminTool/RequestDialog.java

@@ -0,0 +1,1101 @@
+package jplagAdminTool;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+import javax.swing.JRootPane;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.KeyStroke;
+
+import jplagWsClient.jplagClient.FinishRequestData;
+import jplagWsClient.jplagClient.RequestData;
+
+public class RequestDialog extends JDialog {
+
+	private static final long serialVersionUID = 1601751795315331307L;
+	private javax.swing.JPanel jContentPane = null;
+	private JPanel jPanel = null;
+	private JLabel jLabel = null;
+	private JTextField jRealNameTextField = null;
+	private JLabel jLabel1 = null;
+	private JTextField jUsernameTextField = null;
+	private JLabel jLabel2 = null;
+	private JTextField jPasswordTextField = null;
+	private JLabel jLabel3 = null;
+	private JTextField jEmailTextField = null;
+	private JLabel jLabel4 = null;
+	private JTextField jEmailSecondTextField = null;
+	private JLabel jLabel5 = null;
+	private JTextField jHomepageTextField = null;
+	private JLabel jLabel6 = null;
+	private JLabel jLabel7 = null;
+	private JPanel jPanel1 = null;
+	private JButton jAcceptButton = null;
+	private JButton jDeclineButton = null;
+	private JButton jPreviousButton = null;
+	private JButton jNextButton = null;
+	private JButton jCloseButton = null;
+	private JPanel jPanel2 = null;
+	private JLabel jRequestNumLabel = null;
+	private JPanel jPanel3 = null;
+
+	private RequestData[] reqdatas;
+	private String[] oldUsernames;
+	private String[] expireStrs;
+    private String[] notesStrs;
+	private AdminTool adminTool;
+	
+	private int reqind=0;
+	private JTextField jExpireTextField = null;
+	private JLabel jStateLabel = null;
+    
+	private enum RequestState { open, accepted, declined, processing }
+	
+	private RequestState[] states=null;
+	private JTextArea jReasonTextArea = null;
+	private JTextArea jNotesTextArea = null;
+	private JScrollPane jScrollPane = null;
+	private JScrollPane jScrollPane1 = null;
+	private JProgressBar jProgressBar = null;
+	private JPanel jPanel4 = null;
+	private JLabel jLabel9 = null;
+	private JLabel jLabel10 = null;
+	private JLabel jLabel8 = null;
+	private JTextField jRequestTimeField = null;
+	private JScrollPane jNotesServerScrollPane = null;
+	private JTextArea jNotesServerTextArea = null;
+    private JButton jShowHomepageButton = null;
+    private JButton jShowMailProviderButton = null;
+    private JLabel jUserStateLabel = null;
+    private JComboBox<String> jStateComboBox = null;
+	
+	/**
+	 * This is the default constructor
+	 */
+	public RequestDialog(RequestData[] rds, AdminTool at) {
+		super(at);
+		reqdatas = rds;
+		states = new RequestState[rds.length];
+		for(int i=0; i<states.length; i++) states[i] = RequestState.open;
+		GregorianCalendar c = new GregorianCalendar(
+            TimeZone.getTimeZone("GMT"));
+		c.add(Calendar.YEAR,1);
+		String calstr = formatCalendar(c);
+        oldUsernames = new String[rds.length];
+        notesStrs = new String[rds.length];
+        expireStrs = new String[rds.length];
+		for(int i=0; i<rds.length; i++) {
+			oldUsernames[i] = reqdatas[i].getUsername();
+            notesStrs[i] = "";
+            expireStrs[i] = calstr;
+        }
+		adminTool = at;
+		initialize();
+		setData();
+	}
+    
+    private void doClose() {
+        setVisible(false);
+        dispose();
+        adminTool.updateRequestsWaiting();
+    }
+
+	protected JRootPane createRootPane() {
+		KeyStroke stroke=KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
+		JRootPane rootPane=new JRootPane();
+		rootPane.registerKeyboardAction(new ActionListener() {
+				public void actionPerformed(ActionEvent actionEvent) {
+                    doClose();
+				}
+			}, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
+		
+		return rootPane;
+	}
+	
+	/**
+	 * This method initializes this
+	 * 
+	 * @return void
+	 */
+	private void initialize() {
+		this.setSize(601, 568);
+		this.setTitle("Request dialog");
+		this.setResizable(false);
+		this.setContentPane(getJContentPane());
+	}
+
+	/**
+	 * This method initializes jContentPane
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	private javax.swing.JPanel getJContentPane() {
+		if(jContentPane == null) {
+			jContentPane = new javax.swing.JPanel();
+			jContentPane.setLayout(new java.awt.BorderLayout());
+			jContentPane.add(getJPanel2(), java.awt.BorderLayout.NORTH);
+			jContentPane.add(getJPanel3(), java.awt.BorderLayout.CENTER);
+			jContentPane.add(getJPanel1(), java.awt.BorderLayout.SOUTH);
+		}
+		return jContentPane;
+	}
+
+	/**
+	 * This method initializes jPanel2	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */    
+	private JPanel getJPanel2() {
+		if (jPanel2 == null) {
+			jRequestNumLabel = new JLabel();
+			jRequestNumLabel.setText("Request 1/999");
+			jStateLabel = new JLabel();
+			jStateLabel.setText("State of request: blub");
+			jPanel2 = new JPanel();
+			FlowLayout flowLayout19 = new FlowLayout();
+			flowLayout19.setHgap(50);
+			jPanel2.setLayout(flowLayout19);
+			jPanel2.add(jRequestNumLabel, null);
+			jPanel2.add(jStateLabel, null);
+			jPanel2.add(getJProgressBar(), null);
+		}
+		return jPanel2;
+	}
+
+	/**
+	 * This method initializes jProgressBar	
+	 * 	
+	 * @return javax.swing.JProgressBar	
+	 */    
+	private JProgressBar getJProgressBar() {
+		if (jProgressBar == null) {
+			jProgressBar = new JProgressBar();
+			jProgressBar.setPreferredSize(new java.awt.Dimension(50,14));
+		}
+		return jProgressBar;
+	}
+	
+	/**
+	 * This method initializes jPanel3	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */    
+	private JPanel getJPanel3() {
+		if (jPanel3 == null) {
+			jPanel3 = new JPanel();
+			jPanel3.setLayout(new BorderLayout());
+			jPanel3.setBorder(javax.swing.BorderFactory.createEmptyBorder(5,5,5,5));
+			jPanel3.add(getJPanel(), java.awt.BorderLayout.NORTH);
+			jPanel3.add(getJPanel4(), java.awt.BorderLayout.SOUTH);
+		}
+		return jPanel3;
+	}
+	
+	/**
+	 * This method initializes jPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */    
+	private JPanel getJPanel() {
+		if (jPanel == null) {
+			GridBagConstraints gridBagConstraints19 = new GridBagConstraints();
+			gridBagConstraints19.gridx = 3;
+			gridBagConstraints19.gridy = 4;
+			GridBagConstraints gridBagConstraints = new GridBagConstraints();
+			gridBagConstraints.gridx = 3;
+			gridBagConstraints.gridy = 6;
+			GridBagConstraints gridBagConstraints24 = new GridBagConstraints();
+			gridBagConstraints24.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints24.gridx = 2;
+			gridBagConstraints24.gridy = 0;
+			gridBagConstraints24.gridwidth = 2;
+			gridBagConstraints24.weightx = 1.0;
+			GridBagConstraints gridBagConstraints17 = new GridBagConstraints();
+			gridBagConstraints17.gridx = 0;
+			gridBagConstraints17.gridy = 0;
+			gridBagConstraints17.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel8 = new JLabel();
+			jLabel8.setText("Request time:");
+			GridBagConstraints gridBagConstraints23 = new GridBagConstraints();
+			gridBagConstraints23.fill = java.awt.GridBagConstraints.BOTH;
+			gridBagConstraints23.gridx = 2;
+			gridBagConstraints23.gridy = 8;
+			gridBagConstraints23.weightx = 1.0;
+			gridBagConstraints23.gridwidth = 2;
+			gridBagConstraints23.weighty = 1.0;
+			GridBagConstraints gridBagConstraints22 = new GridBagConstraints();
+			gridBagConstraints22.fill = java.awt.GridBagConstraints.BOTH;
+			gridBagConstraints22.gridx = 2;
+			gridBagConstraints22.gridy = 7;
+			gridBagConstraints22.weightx = 1.0;
+			gridBagConstraints22.gridwidth = 2;
+			gridBagConstraints22.weighty = 1.0;
+			GridBagConstraints gridBagConstraints21 = new GridBagConstraints();
+			gridBagConstraints21.fill = java.awt.GridBagConstraints.BOTH;
+			gridBagConstraints21.gridx = 2;
+			gridBagConstraints21.gridy = 7;
+			gridBagConstraints21.weightx = 1.0;
+			gridBagConstraints21.weighty = 1.0;
+			GridBagConstraints gridBagConstraints20 = new GridBagConstraints();
+			gridBagConstraints20.fill = java.awt.GridBagConstraints.BOTH;
+			gridBagConstraints20.gridx = 2;
+			gridBagConstraints20.gridy = 6;
+			gridBagConstraints20.weightx = 1.0;
+			gridBagConstraints20.weighty = 1.0;
+			GridBagConstraints gridBagConstraints15 = new GridBagConstraints();
+			gridBagConstraints15.gridx = 0;
+			gridBagConstraints15.gridy = 8;
+			gridBagConstraints15.anchor = java.awt.GridBagConstraints.NORTHWEST;
+			jLabel7 = new JLabel();
+			jLabel7.setText("Additional notes:");
+			GridBagConstraints gridBagConstraints13 = new GridBagConstraints();
+			gridBagConstraints13.gridx = 0;
+			gridBagConstraints13.gridy = 7;
+			gridBagConstraints13.anchor = java.awt.GridBagConstraints.NORTHWEST;
+			jLabel6 = new JLabel();
+			jLabel6.setText("Reason:");
+			GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
+			gridBagConstraints12.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints12.gridx = 2;
+			gridBagConstraints12.gridy = 6;
+			gridBagConstraints12.weightx = 1.0;
+			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
+			gridBagConstraints11.gridx = 0;
+			gridBagConstraints11.gridy = 6;
+			gridBagConstraints11.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel5 = new JLabel();
+			jLabel5.setText("Homepage:");
+			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
+			gridBagConstraints10.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints10.gridx = 2;
+			gridBagConstraints10.gridy = 5;
+			gridBagConstraints10.gridwidth = 2;
+			gridBagConstraints10.weightx = 1.0;
+			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
+			gridBagConstraints9.gridx = 0;
+			gridBagConstraints9.gridy = 5;
+			gridBagConstraints9.anchor = java.awt.GridBagConstraints.WEST;
+			gridBagConstraints9.insets = new java.awt.Insets(0,0,0,5);
+			gridBagConstraints9.ipadx = 71;
+			jLabel4 = new JLabel();
+			jLabel4.setText("Secondary email:");
+			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
+			gridBagConstraints8.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints8.gridx = 2;
+			gridBagConstraints8.gridy = 4;
+			gridBagConstraints8.gridwidth = 1;
+			gridBagConstraints8.weightx = 1.0;
+			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
+			gridBagConstraints7.gridx = 0;
+			gridBagConstraints7.gridy = 4;
+			gridBagConstraints7.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel3 = new JLabel();
+			jLabel3.setText("Primary email:");
+			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
+			gridBagConstraints6.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints6.gridx = 2;
+			gridBagConstraints6.gridy = 3;
+			gridBagConstraints6.gridwidth = 2;
+			gridBagConstraints6.weightx = 1.0;
+			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
+			gridBagConstraints5.gridx = 0;
+			gridBagConstraints5.gridy = 3;
+			gridBagConstraints5.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel2 = new JLabel();
+			jLabel2.setText("Password:");
+			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
+			gridBagConstraints4.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints4.gridx = 2;
+			gridBagConstraints4.gridy = 2;
+			gridBagConstraints4.gridwidth = 2;
+			gridBagConstraints4.weightx = 1.0;
+			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
+			gridBagConstraints3.gridx = 0;
+			gridBagConstraints3.gridy = 2;
+			gridBagConstraints3.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel1 = new JLabel();
+			jLabel1.setText("Username:");
+			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
+			gridBagConstraints2.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints2.gridx = 2;
+			gridBagConstraints2.gridy = 1;
+			gridBagConstraints2.weightx = 1.0;
+			gridBagConstraints2.gridwidth = 2;
+			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
+			gridBagConstraints1.gridx = 0;
+			gridBagConstraints1.gridy = 1;
+			gridBagConstraints1.anchor = java.awt.GridBagConstraints.WEST;
+			jLabel = new JLabel();
+			jLabel.setText("Real name:");
+			jPanel = new JPanel();
+			jPanel.setLayout(new GridBagLayout());
+			jPanel.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.RAISED), javax.swing.BorderFactory.createEmptyBorder(5,5,5,5)));
+			jPanel.add(getJRequestTimeField(), gridBagConstraints24);
+			jPanel.add(jLabel8, gridBagConstraints17);
+			jPanel.add(jLabel7, gridBagConstraints15);
+			jPanel.add(jLabel6, gridBagConstraints13);
+			jPanel.add(getJHomepageTextField(), gridBagConstraints12);
+			jPanel.add(jLabel5, gridBagConstraints11);
+			jPanel.add(getJEmailSecondTextField(), gridBagConstraints10);
+			jPanel.add(jLabel4, gridBagConstraints9);
+			jPanel.add(getJEmailTextField(), gridBagConstraints8);
+			jPanel.add(jLabel3, gridBagConstraints7);
+			jPanel.add(getJPasswordTextField(), gridBagConstraints6);
+			jPanel.add(jLabel2, gridBagConstraints5);
+			jPanel.add(getJUsernameTextField(), gridBagConstraints4);
+			jPanel.add(jLabel1, gridBagConstraints3);
+			jPanel.add(getJRealNameTextField(), gridBagConstraints2);
+			jPanel.add(jLabel, gridBagConstraints1);
+			jPanel.add(getJScrollPane(), gridBagConstraints22);
+			jPanel.add(getJScrollPane1(), gridBagConstraints23);
+			jPanel.add(getJShowHomepageButton(), gridBagConstraints);
+			jPanel.add(getJShowMailProviderButton(), gridBagConstraints19);
+		}
+		return jPanel;
+	}
+
+	/**
+	 * This method initializes jRequestTimeField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJRequestTimeField() {
+		if (jRequestTimeField == null) {
+			jRequestTimeField = new JTextField();
+			jRequestTimeField.setEditable(false);
+		}
+		return jRequestTimeField;
+	}
+	
+	/**
+	 * This method initializes jRealNameTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJRealNameTextField() {
+		if (jRealNameTextField == null) {
+			jRealNameTextField = new JTextField();
+		}
+		return jRealNameTextField;
+	}
+
+	/**
+	 * This method initializes jUsernameTextField
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJUsernameTextField() {
+		if (jUsernameTextField == null) {
+			jUsernameTextField = new JTextField();
+		}
+		return jUsernameTextField;
+	}
+
+	/**
+	 * This method initializes jPasswordTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJPasswordTextField() {
+		if (jPasswordTextField == null) {
+			jPasswordTextField = new JTextField();
+		}
+		return jPasswordTextField;
+	}
+
+	/**
+	 * This method initializes jEmailTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJEmailTextField() {
+		if (jEmailTextField == null) {
+			jEmailTextField = new JTextField();
+		}
+		return jEmailTextField;
+	}
+
+	/**
+	 * This method initializes jEmailSecondTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJEmailSecondTextField() {
+		if (jEmailSecondTextField == null) {
+			jEmailSecondTextField = new JTextField();
+		}
+		return jEmailSecondTextField;
+	}
+
+	/**
+	 * This method initializes jHomepageTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJHomepageTextField() {
+		if (jHomepageTextField == null) {
+			jHomepageTextField = new JTextField();
+		}
+		return jHomepageTextField;
+	}
+
+	/**
+	 * This method initializes jScrollPane	
+	 * 	
+	 * @return javax.swing.JScrollPane	
+	 */    
+	private JScrollPane getJScrollPane() {
+		if (jScrollPane == null) {
+			jScrollPane = new JScrollPane();
+			jScrollPane.setViewportView(getJReasonTextArea());
+		}
+		return jScrollPane;
+	}
+
+	/**
+	 * This method initializes jReasonTextArea	
+	 * 	
+	 * @return javax.swing.JTextArea	
+	 */    
+	private JTextArea getJReasonTextArea() {
+		if (jReasonTextArea == null) {
+			jReasonTextArea = new JTextArea();
+			jReasonTextArea.setRows(7);
+			jReasonTextArea.setLineWrap(true);
+			jReasonTextArea.setWrapStyleWord(true);
+			jReasonTextArea.setEditable(false);
+			jReasonTextArea.setBackground(javax.swing.UIManager
+				      .getColor("Button.background"));
+		}
+		return jReasonTextArea;
+	}
+
+	/**
+	 * This method initializes jScrollPane1	
+	 * 	
+	 * @return javax.swing.JScrollPane	
+	 */    
+	private JScrollPane getJScrollPane1() {
+		if (jScrollPane1 == null) {
+			jScrollPane1 = new JScrollPane();
+			jScrollPane1.setViewportView(getJNotesTextArea());
+		}
+		return jScrollPane1;
+	}
+	
+	/**
+	 * This method initializes jNotesTextArea
+	 * 	
+	 * @return javax.swing.JTextArea	
+	 */    
+	private JTextArea getJNotesTextArea() {
+		if (jNotesTextArea == null) {
+			jNotesTextArea = new JTextArea();
+			jNotesTextArea.setRows(6);
+			jNotesTextArea.setLineWrap(true);
+			jNotesTextArea.setWrapStyleWord(true);
+			jNotesTextArea.setEditable(false);
+			jNotesTextArea.setBackground(javax.swing.UIManager
+				      .getColor("Button.background"));
+		}
+		return jNotesTextArea;
+	}
+
+	/**
+	 * This method initializes jPanel4	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */    
+	private JPanel getJPanel4() {
+		if (jPanel4 == null) {
+			GridBagConstraints gridBagConstraints26 = new GridBagConstraints();
+			gridBagConstraints26.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints26.gridy = 2;
+			gridBagConstraints26.weightx = 1.0;
+			gridBagConstraints26.gridx = 1;
+			GridBagConstraints gridBagConstraints25 = new GridBagConstraints();
+			gridBagConstraints25.gridx = 0;
+			gridBagConstraints25.anchor = java.awt.GridBagConstraints.WEST;
+			gridBagConstraints25.gridy = 2;
+			jUserStateLabel = new JLabel();
+			jUserStateLabel.setText("User state:");
+			GridBagConstraints gridBagConstraints18 = new GridBagConstraints();
+			gridBagConstraints18.fill = java.awt.GridBagConstraints.BOTH;
+			gridBagConstraints18.gridx = 1;
+			gridBagConstraints18.gridy = 0;
+			gridBagConstraints18.weightx = 1.0;
+			gridBagConstraints18.weighty = 1.0;
+			GridBagConstraints gridBagConstraints16 = new GridBagConstraints();
+            gridBagConstraints16.anchor = java.awt.GridBagConstraints.NORTHWEST;
+			gridBagConstraints16.gridx = 0;
+			gridBagConstraints16.gridy = 0;
+			GridBagConstraints gridBagConstraints14 = new GridBagConstraints();
+			gridBagConstraints14.fill = java.awt.GridBagConstraints.HORIZONTAL;
+			gridBagConstraints14.gridx = 1;
+			gridBagConstraints14.gridy = 1;
+			gridBagConstraints14.weightx = 1.0;
+			GridBagConstraints gridBagConstraints131 = new GridBagConstraints();
+			gridBagConstraints131.gridx = 0;
+			gridBagConstraints131.gridy = 1;
+			gridBagConstraints131.insets = new java.awt.Insets(0,0,0,5);
+			jLabel10 = new JLabel();
+			jLabel10.setText("Expiration date (DD.MM.YYYY):");
+			jLabel9 = new JLabel();
+			jLabel9.setText("Notes:");
+			jPanel4 = new JPanel();
+			jPanel4.setLayout(new GridBagLayout());
+			jPanel4.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.RAISED), javax.swing.BorderFactory.createEmptyBorder(5,5,5,5)));
+			jPanel4.add(getJNotesServerScrollPane(), gridBagConstraints18);
+			jPanel4.add(getJExpireTextField(), gridBagConstraints14);
+			jPanel4.add(jLabel10, gridBagConstraints131);
+			jPanel4.add(jLabel9, gridBagConstraints16);
+			jPanel4.add(jUserStateLabel, gridBagConstraints25);
+			jPanel4.add(getJStateComboBox(), gridBagConstraints26);
+		}
+		return jPanel4;
+	}
+
+	/**
+	 * This method initializes jExpireTextField	
+	 * 	
+	 * @return javax.swing.JTextField	
+	 */    
+	private JTextField getJExpireTextField() {
+		if (jExpireTextField == null) {
+			jExpireTextField = new JTextField();
+		}
+		return jExpireTextField;
+	}
+
+	/**
+	 * This method initializes jPanel1	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */    
+	private JPanel getJPanel1() {
+		if (jPanel1 == null) {
+			jPanel1 = new JPanel();
+			jPanel1.add(getJAcceptButton(), null);
+			jPanel1.add(getJDeclineButton(), null);
+			jPanel1.add(getJPreviousButton(), null);
+			jPanel1.add(getJNextButton(), null);
+			jPanel1.add(getJCloseButton(), null);
+		}
+		return jPanel1;
+	}
+
+    public static Calendar parseCalendar(String string)
+		throws ParseException
+	{
+		if(string.length()==0) return null;
+		
+		Calendar cal=new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+		SimpleDateFormat sdf2=new SimpleDateFormat("dd.MM.yy");
+		SimpleDateFormat sdf4=new SimpleDateFormat("dd.MM.yyyy");
+		sdf2.setLenient(false);
+		sdf4.setLenient(false);
+		Date date;
+		try
+		{
+			date=sdf2.parse(string);
+		}
+		catch(ParseException e)
+		{
+			date=sdf4.parse(string);
+		}
+		cal.setTime(date);
+		return cal;
+	}
+
+	public static String formatCalendar(Calendar cal) {
+		if(cal==null) return "No date";
+		DateFormat df=DateFormat.getDateInstance(DateFormat.MEDIUM,Locale.GERMAN);
+		return df.format(cal.getTime());
+	}
+	
+	/**
+	 * This method initializes jAcceptButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJAcceptButton() {
+		if (jAcceptButton == null) {
+			jAcceptButton = new JButton();
+			jAcceptButton.setText("Accept request...");
+			jAcceptButton.addActionListener(new java.awt.event.ActionListener() { 
+				private String mailString;
+				private String mailSubjectString;
+				private Calendar expires;
+                private int userstate;
+				
+				public void actionPerformed(java.awt.event.ActionEvent e) {    
+					final SwingWorker worker = new SwingWorker() {
+						private FinishRequestData finishData;
+						private int curReqInd;
+						
+						public Object construct() {
+							try
+							{
+								curReqInd=reqind;
+                                RequestData rd=reqdatas[curReqInd];
+                                finishData=new FinishRequestData(
+                                        oldUsernames[curReqInd],
+                                        rd.getUsername(), rd.getPassword(),
+                                        expires, rd.getRealName(),
+                                        rd.getEmail(), rd.getEmailSecond(),
+                                        rd.getHomepage(), rd.getReason(),
+                                        strToN(notesStrs[curReqInd]),
+                                        userstate,
+                                        mailSubjectString,
+                                        mailString);
+								
+                                adminTool.getJPlagStub().finishAccountRequest(
+										finishData);
+								return new Object();
+							}
+							catch(Exception ex)
+							{
+								adminTool.CheckException(ex,RequestDialog.this);
+							}							
+							return null;
+						}
+						
+						public void finished() {
+							if(get()!=null)
+							{
+								states[curReqInd] = RequestState.accepted;
+								Calendar cal = Calendar.getInstance(
+										TimeZone.getTimeZone("GMT"));
+								BackedUserData data = new BackedUserData(
+										finishData.getUsername(),
+										finishData.getPassword(),
+										cal,adminTool.getUsername(),
+										finishData.getExpires(),null,0,
+										finishData.getRealName(),
+										finishData.getEmail(),
+										finishData.getEmailSecond(),
+										finishData.getHomepage(),
+										finishData.getReason(),
+										finishData.getNotes(),
+										userstate);
+								adminTool.getUserTableModel().addNewUser(data);
+                                if(reqind<reqdatas.length-1)
+                                {
+                                    reqind++;
+                                    setData();
+                                }
+                                else updateState();
+							}
+                            else {
+                                states[curReqInd] = RequestState.open;
+                                updateState();
+                            }
+						}
+					};
+					
+					// check and set expires
+					try
+					{
+						expires=parseCalendar(getJExpireTextField().getText());
+
+						if(expires!=null)
+						{
+							Calendar cal=Calendar.getInstance(
+									TimeZone.getTimeZone("GMT"));
+							if(cal.after(expires))
+							{
+								JOptionPane.showMessageDialog(
+										RequestDialog.this,
+										"Please check the expire date field!",
+										"Expire date is already expired!",
+										JOptionPane.ERROR_MESSAGE);
+								return;
+							}
+						}
+					}
+					catch(ParseException ex)
+					{
+						JOptionPane.showMessageDialog(
+								RequestDialog.this,
+								"Please check the expire date field!",
+								"Illegal expire date!",
+								JOptionPane.ERROR_MESSAGE);
+						return;
+					}
+					
+					RequestData rd = new RequestData(null,
+							getJUsernameTextField().getText(),
+							getJPasswordTextField().getText(),
+							getJRealNameTextField().getText(),
+							getJEmailTextField().getText(),
+							strToN(getJEmailSecondTextField().getText()),
+							strToN(getJHomepageTextField().getText()),
+							getJReasonTextArea().getText(),
+							strToN(getJNotesServerTextArea().getText()));
+					
+					// Let user choose the message to be sent to the user
+					MailDialog md = new MailDialog(MailDialog.MAIL_ACCEPTED,
+							"Choose mail to be sent to the accepted user...",
+							rd, RequestDialog.this, adminTool);
+					md.setLocationRelativeTo(RequestDialog.this);
+					md.setVisible(true);
+					
+					if(!md.isCancelled())
+					{
+						mailString = md.getMailString();
+						mailSubjectString = md.getMailSubjectString();
+                        states[reqind] = RequestState.processing;
+                        userstate = BackedUserData.getStateInt(
+                            (String) jStateComboBox.getSelectedItem());
+                        updateState();
+                        updateChanges();
+						worker.start();
+					}
+				}
+			});
+		}
+		return jAcceptButton;
+	}
+
+	/**
+	 * This method initializes jDeclineButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJDeclineButton() {
+		if (jDeclineButton == null) {
+			jDeclineButton = new JButton();
+			jDeclineButton.setText("Decline request...");
+			jDeclineButton.addActionListener(new java.awt.event.ActionListener() { 
+				private String mailString;
+				private String mailSubjectString;
+				public void actionPerformed(java.awt.event.ActionEvent e) {    
+					final SwingWorker worker = new SwingWorker() {
+						private int curReqInd;
+						
+						public Object construct() {
+							try
+							{
+								curReqInd=reqind;
+                                RequestData rd=reqdatas[curReqInd];
+                                FinishRequestData fd=new FinishRequestData(
+                                        oldUsernames[curReqInd],
+                                        rd.getUsername(), null, null,
+                                        rd.getRealName(), rd.getEmail(),
+                                        rd.getEmailSecond(), rd.getHomepage(),
+                                        rd.getReason(),
+                                        strToN(notesStrs[curReqInd]),
+                                        null,
+                                        mailSubjectString,
+                                        mailString);
+										
+								adminTool.getJPlagStub().finishAccountRequest(fd);
+								return new Object();
+							}
+							catch(Exception ex)
+							{
+								adminTool.CheckException(ex,RequestDialog.this);
+							}							
+							return null;
+						}
+						
+						public void finished() {
+							if(get()!=null)
+							{
+								states[curReqInd] = RequestState.declined;
+                                if(reqind<reqdatas.length-1)
+                                {
+                                    reqind++;
+                                    setData();
+                                }
+                                else updateState();
+							}
+                            else getJProgressBar().setIndeterminate(false);
+						}
+					};
+					RequestData rd = new RequestData(null,
+							getJUsernameTextField().getText(),
+							getJPasswordTextField().getText(),
+							getJRealNameTextField().getText(),
+							getJEmailTextField().getText(),
+							strToN(getJEmailSecondTextField().getText()),
+							strToN(getJHomepageTextField().getText()),
+							getJReasonTextArea().getText(),
+							strToN(getJNotesServerTextArea().getText()));
+					MailDialog md = new MailDialog(MailDialog.MAIL_DECLINED,
+							"Choose mail to be sent to the declined user...",
+							rd, RequestDialog.this, adminTool);
+                    md.setLocationRelativeTo(RequestDialog.this);
+					md.setVisible(true);
+                    
+					if(!md.isCancelled())
+					{
+						mailString = md.getMailString();
+						mailSubjectString = md.getMailSubjectString();
+                        states[reqind] = RequestState.processing;
+                        updateState();
+                        updateChanges();
+						worker.start();
+					}
+				}
+			});
+		}
+		return jDeclineButton;
+	}
+	
+	/**
+	 * "Nillable to string"
+	 * @return "" if str==null, str otherwise
+	 */
+	private String nToStr(String str) {
+		if(str==null) return "";
+		else return str;
+	}
+	
+	/**
+	 * "String to nillable"
+	 * @return null if str=="", str otherwise
+	 */
+	private String strToN(String str) {
+		if(str.length()==0) return null;
+		else return str;
+	}
+	
+	private void updateState() {
+		String stateText;
+		switch(states[reqind]) {
+			case open: stateText = "open"; break;
+			case accepted: stateText = "accepted"; break;
+			case declined: stateText = "declined"; break;
+			case processing: stateText = "processing"; break;
+			default: stateText = "buggy *cough*"; break;
+		}
+        switch(states[reqind]) {
+            case open:
+                getJProgressBar().setValue(0);
+                getJProgressBar().setIndeterminate(false);
+                break;
+            case accepted:
+            case declined:
+                getJProgressBar().setValue(100);
+                getJProgressBar().setIndeterminate(false);
+                break;
+            case processing:
+                getJProgressBar().setIndeterminate(true);
+                break;
+        }
+		jStateLabel.setText("State of request: " + stateText);
+		getJAcceptButton().setEnabled(states[reqind]==RequestState.open);
+		getJDeclineButton().setEnabled(states[reqind]==RequestState.open);
+	}
+	
+	private void setData() {
+		RequestData rd = reqdatas[reqind];
+		getJRequestTimeField().setText(rd.getValidateTime());
+		getJRealNameTextField().setText(rd.getRealName());
+		getJUsernameTextField().setText(rd.getUsername());
+		getJPasswordTextField().setText(rd.getPassword());
+		getJEmailTextField().setText(rd.getEmail());
+		getJEmailSecondTextField().setText(nToStr(rd.getEmailSecond()));
+		getJHomepageTextField().setText(nToStr(rd.getHomepage()));
+		getJReasonTextArea().setText(rd.getReason());
+        getJReasonTextArea().setCaretPosition(0);
+		getJNotesTextArea().setText(nToStr(rd.getNotes()));
+        getJNotesTextArea().setCaretPosition(0);
+        getJNotesServerTextArea().setText(notesStrs[reqind]);
+        getJNotesServerTextArea().setCaretPosition(0);
+		getJExpireTextField().setText(expireStrs[reqind]);
+		
+		jRequestNumLabel.setText("Request " + (reqind+1) + "/"
+				+ reqdatas.length);
+		updateState();
+		getJPreviousButton().setEnabled(reqind!=0);
+		getJNextButton().setEnabled(reqind<reqdatas.length-1);
+	}
+
+	private void updateChanges() {
+		RequestData rd=reqdatas[reqind];
+		rd.setRealName(getJRealNameTextField().getText());
+		rd.setUsername(getJUsernameTextField().getText());
+		rd.setPassword(getJPasswordTextField().getText());
+		rd.setEmail(getJEmailTextField().getText());
+		rd.setEmailSecond(strToN(getJEmailSecondTextField().getText()));
+		rd.setHomepage(strToN(getJHomepageTextField().getText()));
+        notesStrs[reqind]=getJNotesServerTextArea().getText();
+		expireStrs[reqind]=getJExpireTextField().getText();
+	}
+
+	/**
+	 * This method initializes jPreviousButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJPreviousButton() {
+		if (jPreviousButton == null) {
+			jPreviousButton = new JButton();
+			jPreviousButton.setText("Show previous");
+			jPreviousButton.addActionListener(new java.awt.event.ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {    
+					if(reqind>0)
+					{
+						updateChanges();
+						reqind--;
+						setData();
+					}
+				}
+			});
+		}
+		return jPreviousButton;
+	}
+
+	/**
+	 * This method initializes jNextButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJNextButton() {
+		if (jNextButton == null) {
+			jNextButton = new JButton();
+			jNextButton.setText("Show next");
+			jNextButton.addActionListener(new java.awt.event.ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {    
+					if(reqind<reqdatas.length-1)
+					{
+						updateChanges();
+						reqind++;
+						setData();
+					}
+				}
+			});
+		}
+		return jNextButton;
+	}
+
+	/**
+	 * This method initializes jCloseButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */    
+	private JButton getJCloseButton() {
+		if (jCloseButton == null) {
+			jCloseButton = new JButton();
+			jCloseButton.setText("Close");
+			jCloseButton.addActionListener(new java.awt.event.ActionListener() { 
+				public void actionPerformed(java.awt.event.ActionEvent e) {    
+                    doClose();
+				}
+			});
+		}
+		return jCloseButton;
+	}
+
+	/**
+	 * This method initializes jNotesServerScrollPane	
+	 * 	
+	 * @return javax.swing.JScrollPane	
+	 */    
+	private JScrollPane getJNotesServerScrollPane() {
+		if (jNotesServerScrollPane == null) {
+			jNotesServerScrollPane = new JScrollPane();
+			jNotesServerScrollPane.setViewportView(getJNotesServerTextArea());
+		}
+		return jNotesServerScrollPane;
+	}
+
+	/**
+	 * This method initializes jNotesServerTextArea	
+	 * 	
+	 * @return javax.swing.JTextArea	
+	 */    
+	private JTextArea getJNotesServerTextArea() {
+		if (jNotesServerTextArea == null) {
+			jNotesServerTextArea = new JTextArea();
+			jNotesServerTextArea.setRows(3);
+			jNotesServerTextArea.setLineWrap(true);
+			jNotesServerTextArea.setWrapStyleWord(true);
+		}
+		return jNotesServerTextArea;
+	}
+
+    /**
+     * This method initializes jShowHomepageButton	
+     * 	
+     * @return javax.swing.JButton	
+     */
+    private JButton getJShowHomepageButton() {
+        if(jShowHomepageButton == null) {
+            jShowHomepageButton = new JButton();
+            jShowHomepageButton.setText("Show");
+            jShowHomepageButton.setPreferredSize(new java.awt.Dimension(40,18));
+            jShowHomepageButton.setMargin(new java.awt.Insets(2,2,2,2));
+            jShowHomepageButton.setFont(new java.awt.Font("Dialog", java.awt.Font.BOLD, 10));
+            jShowHomepageButton.addActionListener(new java.awt.event.ActionListener() {
+                public void actionPerformed(java.awt.event.ActionEvent e) {
+                    AdminTool.showHomepage(getJHomepageTextField().getText(),
+                        RequestDialog.this);
+                }
+            });
+        }
+        return jShowHomepageButton;
+    }
+
+    /**
+     * This method initializes jShowMailProviderButton	
+     * 	
+     * @return javax.swing.JButton	
+     */
+    private JButton getJShowMailProviderButton() {
+        if(jShowMailProviderButton == null) {
+            jShowMailProviderButton = new JButton();
+            jShowMailProviderButton.setText("Show");
+            jShowMailProviderButton.setFont(new java.awt.Font("Dialog", java.awt.Font.BOLD, 10));
+            jShowMailProviderButton.setMargin(new java.awt.Insets(2,2,2,2));
+            jShowMailProviderButton.setPreferredSize(new java.awt.Dimension(40,18));
+            jShowMailProviderButton.addActionListener(new java.awt.event.ActionListener() {
+                public void actionPerformed(java.awt.event.ActionEvent e) {
+                    String provider = getJEmailTextField().getText();
+                    provider = "http://www."
+                        + provider.substring(provider.indexOf('@')+1);
+                    AdminTool.showHomepage(provider, RequestDialog.this);
+                }
+            });
+        }
+        return jShowMailProviderButton;
+    }
+
+    /**
+     * This method initializes jStateComboBox	
+     * 	
+     * @return javax.swing.JComboBox	
+     */
+    private JComboBox<String> getJStateComboBox() {
+        if(jStateComboBox == null) {
+			jStateComboBox = new JComboBox<String>(BackedUserData.getStateNameArray(
+                BackedUserData.USER_JPLAGADMIN));
+        }
+        return jStateComboBox;
+    }
+}  //  @jve:decl-index=0:visual-constraint="10,10"

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
jplag.adminTool/src/main/java/jplagAdminTool/SwingWorker.java


+ 502 - 0
jplag.adminTool/src/main/java/jplagAdminTool/TableSorter.java

@@ -0,0 +1,502 @@
+package jplagAdminTool;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.Icon;
+import javax.swing.JLabel;
+import javax.swing.JTable;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.JTableHeader;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumnModel;
+import javax.swing.table.TableModel;
+
+/**
+ * TableSorter is a decorator for TableModels; adding sorting
+ * functionality to a supplied TableModel. TableSorter does
+ * not store or copy the data in its TableModel; instead it maintains
+ * a map from the row indexes of the view to the row indexes of the
+ * model. As requests are made of the sorter (like getValueAt(row, col))
+ * they are passed to the underlying model after the row numbers
+ * have been translated via the internal mapping array. This way,
+ * the TableSorter appears to hold another copy of the table
+ * with the rows in a different order.
+ * <p/>
+ * TableSorter registers itself as a listener to the underlying model,
+ * just as the JTable itself would. Events recieved from the model
+ * are examined, sometimes manipulated (typically widened), and then
+ * passed on to the TableSorter's listeners (typically the JTable).
+ * If a change to the model has invalidated the order of TableSorter's
+ * rows, a note of this is made and the sorter will resort the
+ * rows the next time a value is requested.
+ * <p/>
+ * When the tableHeader property is set, either by using the
+ * setTableHeader() method or the two argument constructor, the
+ * table header may be used as a complete UI for TableSorter.
+ * The default renderer of the tableHeader is decorated with a renderer
+ * that indicates the sorting status of each column. In addition,
+ * a mouse listener is installed with the following behavior:
+ * <ul>
+ * <li>
+ * Mouse-click: Clears the sorting status of all other columns
+ * and advances the sorting status of that column through three
+ * values: {NOT_SORTED, ASCENDING, DESCENDING} (then back to
+ * NOT_SORTED again).
+ * <li>
+ * SHIFT-mouse-click: Clears the sorting status of all other columns
+ * and cycles the sorting status of the column through the same
+ * three values, in the opposite order: {NOT_SORTED, DESCENDING, ASCENDING}.
+ * <li>
+ * CONTROL-mouse-click and CONTROL-SHIFT-mouse-click: as above except
+ * that the changes to the column do not cancel the statuses of columns
+ * that are already sorting - giving a way to initiate a compound
+ * sort.
+ * </ul>
+ * <p/>
+ * This is a long overdue rewrite of a class of the same name that
+ * first appeared in the swing table demos in 1997.
+ * 
+ * @author Philip Milne
+ * @author Brendon McLean 
+ * @author Dan van Enckevort
+ * @author Parwinder Sekhon
+ * @version 2.0 02/27/04
+ */
+
+public class TableSorter extends AbstractTableModel {
+	private static final long serialVersionUID = 1L;
+
+	protected TableModel tableModel;
+
+    public static final int DESCENDING = -1;
+    public static final int NOT_SORTED = 0;
+    public static final int ASCENDING = 1;
+
+    private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED);
+
+    public static final Comparator COMPARABLE_COMAPRATOR = new Comparator() {
+        @SuppressWarnings("unchecked")
+        public int compare(Object o1, Object o2) {
+            return ((Comparable) o1).compareTo(o2);
+        }
+    };
+    public static final Comparator LEXICAL_COMPARATOR = new Comparator() {
+        public int compare(Object o1, Object o2) {
+            return o1.toString().toLowerCase().compareTo(o2.toString().toLowerCase());
+        }
+    };
+
+    private Row[] viewToModel;
+    private int[] modelToView;
+
+    private JTableHeader tableHeader;
+    private MouseListener mouseListener;
+    private TableModelListener tableModelListener;
+    private Map<Class, Comparator> columnComparators =
+        new HashMap<Class, Comparator>();
+    private List<Directive> sortingColumns = new ArrayList<Directive>();
+
+    public TableSorter() {
+        this.mouseListener = new MouseHandler();
+        this.tableModelListener = new TableModelHandler();
+    }
+
+    public TableSorter(TableModel tableModel) {
+        this();
+        setTableModel(tableModel);
+    }
+
+    public TableSorter(TableModel tableModel, JTableHeader tableHeader) {
+        this();
+        setTableHeader(tableHeader);
+        setTableModel(tableModel);
+    }
+
+    private void clearSortingState() {
+        viewToModel = null;
+        modelToView = null;
+    }
+
+    public TableModel getTableModel() {
+        return tableModel;
+    }
+
+    public void setTableModel(TableModel tableModel) {
+        if (this.tableModel != null) {
+            this.tableModel.removeTableModelListener(tableModelListener);
+        }
+
+        this.tableModel = tableModel;
+        if (this.tableModel != null) {
+            this.tableModel.addTableModelListener(tableModelListener);
+        }
+
+        clearSortingState();
+        fireTableStructureChanged();
+    }
+
+    public JTableHeader getTableHeader() {
+        return tableHeader;
+    }
+
+    public void setTableHeader(JTableHeader tableHeader) {
+        if (this.tableHeader != null) {
+            this.tableHeader.removeMouseListener(mouseListener);
+            TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer();
+            if (defaultRenderer instanceof SortableHeaderRenderer) {
+                this.tableHeader.setDefaultRenderer(((SortableHeaderRenderer) defaultRenderer).tableCellRenderer);
+            }
+        }
+        this.tableHeader = tableHeader;
+        if (this.tableHeader != null) {
+            this.tableHeader.addMouseListener(mouseListener);
+            this.tableHeader.setDefaultRenderer(
+                    new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer()));
+        }
+    }
+
+    public boolean isSorting() {
+        return sortingColumns.size() != 0;
+    }
+
+    private Directive getDirective(int column) {
+        for (int i = 0; i < sortingColumns.size(); i++) {
+            Directive directive = (Directive)sortingColumns.get(i);
+            if (directive.column == column) {
+                return directive;
+            }
+        }
+        return EMPTY_DIRECTIVE;
+    }
+
+    public int getSortingStatus(int column) {
+        return getDirective(column).direction;
+    }
+
+    private void sortingStatusChanged() {
+        clearSortingState();
+        fireTableDataChanged();
+        if (tableHeader != null) {
+            tableHeader.repaint();
+        }
+    }
+
+    public void setSortingStatus(int column, int status) {
+        Directive directive = getDirective(column);
+        if (directive != EMPTY_DIRECTIVE) {
+            sortingColumns.remove(directive);
+        }
+        if (status != NOT_SORTED) {
+            sortingColumns.add(new Directive(column, status));
+        }
+        sortingStatusChanged();
+    }
+
+    protected Icon getHeaderRendererIcon(int column, int size) {
+        Directive directive = getDirective(column);
+        if (directive == EMPTY_DIRECTIVE) {
+            return null;
+        }
+        return new Arrow(directive.direction == DESCENDING, size, sortingColumns.indexOf(directive));
+    }
+
+    private void cancelSorting() {
+        sortingColumns.clear();
+        sortingStatusChanged();
+    }
+
+    public void setColumnComparator(Class type, Comparator comparator) {
+        if (comparator == null) {
+            columnComparators.remove(type);
+        } else {
+            columnComparators.put(type, comparator);
+        }
+    }
+
+    protected Comparator getComparator(int column) {
+        Class columnType = tableModel.getColumnClass(column);
+        Comparator comparator = (Comparator) columnComparators.get(columnType);
+        if (comparator != null) {
+            return comparator;
+        }
+        if (Comparable.class.isAssignableFrom(columnType)) {
+            return COMPARABLE_COMAPRATOR;
+        }
+        return LEXICAL_COMPARATOR;
+    }
+
+    private Row[] getViewToModel() {
+        if (viewToModel == null) {
+            int tableModelRowCount = tableModel.getRowCount();
+            viewToModel = new Row[tableModelRowCount];
+            for (int row = 0; row < tableModelRowCount; row++) {
+                viewToModel[row] = new Row(row);
+            }
+
+            if (isSorting()) {
+                Arrays.sort(viewToModel);
+            }
+        }
+        return viewToModel;
+    }
+
+    public int modelIndex(int viewIndex) {
+        return getViewToModel()[viewIndex].modelIndex;
+    }
+
+    private int[] getModelToView() {
+        if (modelToView == null) {
+            int n = getViewToModel().length;
+            modelToView = new int[n];
+            for (int i = 0; i < n; i++) {
+                modelToView[modelIndex(i)] = i;
+            }
+        }
+        return modelToView;
+    }
+
+    // TableModel interface methods 
+
+    public int getRowCount() {
+        return (tableModel == null) ? 0 : tableModel.getRowCount();
+    }
+
+    public int getColumnCount() {
+        return (tableModel == null) ? 0 : tableModel.getColumnCount();
+    }
+
+    public String getColumnName(int column) {
+        return tableModel.getColumnName(column);
+    }
+
+    public Class<?> getColumnClass(int column) {
+        return tableModel.getColumnClass(column);
+    }
+
+    public boolean isCellEditable(int row, int column) {
+        return tableModel.isCellEditable(modelIndex(row), column);
+    }
+
+    public Object getValueAt(int row, int column) {
+        return tableModel.getValueAt(modelIndex(row), column);
+    }
+
+    public void setValueAt(Object aValue, int row, int column) {
+        tableModel.setValueAt(aValue, modelIndex(row), column);
+    }
+
+    // Helper classes
+    
+    private class Row implements Comparable {
+        private int modelIndex;
+
+        public Row(int index) {
+            this.modelIndex = index;
+        }
+
+        public int compareTo(Object o) {
+            int row1 = modelIndex;
+            int row2 = ((Row) o).modelIndex;
+
+			for (Iterator<Directive> it = sortingColumns.iterator(); it.hasNext();) {
+				Directive directive = it.next();
+                int column = directive.column;
+                Object o1 = tableModel.getValueAt(row1, column);
+                Object o2 = tableModel.getValueAt(row2, column);
+
+                int comparison = 0;
+                // Define null less than everything, except null.
+                if (o1 == null && o2 == null) {
+                    comparison = 0;
+                } else if (o1 == null) {
+                    comparison = -1;
+                } else if (o2 == null) {
+                    comparison = 1;
+                } else {
+                    comparison = getComparator(column).compare(o1, o2);
+                }
+                if (comparison != 0) {
+                    return directive.direction == DESCENDING ? -comparison : comparison;
+                }
+            }
+            return 0;
+        }
+    }
+
+    private class TableModelHandler implements TableModelListener {
+        public void tableChanged(TableModelEvent e) {
+            // If we're not sorting by anything, just pass the event along.             
+            if (!isSorting()) {
+                clearSortingState();
+                fireTableChanged(e);
+                return;
+            }
+                
+            // If the table structure has changed, cancel the sorting; the             
+            // sorting columns may have been either moved or deleted from             
+            // the model. 
+            if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
+                cancelSorting();
+                fireTableChanged(e);
+                return;
+            }
+
+            // We can map a cell event through to the view without widening             
+            // when the following conditions apply: 
+            // 
+            // a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and, 
+            // b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and,
+            // c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and, 
+            // d) a reverse lookup will not trigger a sort (modelToView != null)
+            //
+            // Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS.
+            // 
+            // The last check, for (modelToView != null) is to see if modelToView 
+            // is already allocated. If we don't do this check; sorting can become 
+            // a performance bottleneck for applications where cells  
+            // change rapidly in different parts of the table. If cells 
+            // change alternately in the sorting column and then outside of             
+            // it this class can end up re-sorting on alternate cell updates - 
+            // which can be a performance problem for large tables. The last 
+            // clause avoids this problem. 
+            int column = e.getColumn();
+            if (e.getFirstRow() == e.getLastRow()
+                    && column != TableModelEvent.ALL_COLUMNS
+                    && getSortingStatus(column) == NOT_SORTED
+                    && modelToView != null) {
+                int viewIndex = getModelToView()[e.getFirstRow()];
+                fireTableChanged(new TableModelEvent(TableSorter.this, 
+                                                     viewIndex, viewIndex, 
+                                                     column, e.getType()));
+                return;
+            }
+
+            // Something has happened to the data that may have invalidated the row order. 
+            clearSortingState();
+            fireTableDataChanged();
+            return;
+        }
+    }
+
+    private class MouseHandler extends MouseAdapter {
+        public void mouseClicked(MouseEvent e) {
+            JTableHeader h = (JTableHeader) e.getSource();
+            TableColumnModel columnModel = h.getColumnModel();
+            int viewColumn = columnModel.getColumnIndexAtX(e.getX());
+            int column = columnModel.getColumn(viewColumn).getModelIndex();
+            if (column != -1) {
+                int status = getSortingStatus(column);
+                if (!e.isControlDown()) {
+                    cancelSorting();
+                }
+                // Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or 
+                // {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is pressed. 
+                status = status + (e.isShiftDown() ? -1 : 1);
+                status = (status + 4) % 3 - 1; // signed mod, returning {-1, 0, 1}
+                setSortingStatus(column, status);
+            }
+        }
+    }
+
+    private static class Arrow implements Icon {
+        private boolean descending;
+        private int size;
+        private int priority;
+
+        public Arrow(boolean descending, int size, int priority) {
+            this.descending = descending;
+            this.size = size;
+            this.priority = priority;
+        }
+
+        public void paintIcon(Component c, Graphics g, int x, int y) {
+            Color color = c == null ? Color.GRAY : c.getBackground();             
+            // In a compound sort, make each succesive triangle 20% 
+            // smaller than the previous one. 
+            int dx = (int)(size/2*Math.pow(0.8, priority));
+            int dy = descending ? dx : -dx;
+            // Align icon (roughly) with font baseline. 
+            y = y + 5*size/6 + (descending ? -dy : 0);
+            int shift = descending ? 1 : -1;
+            g.translate(x, y);
+
+            // Right diagonal. 
+            g.setColor(color.darker());
+            g.drawLine(dx / 2, dy, 0, 0);
+            g.drawLine(dx / 2, dy + shift, 0, shift);
+            
+            // Left diagonal. 
+            g.setColor(color.brighter());
+            g.drawLine(dx / 2, dy, dx, 0);
+            g.drawLine(dx / 2, dy + shift, dx, shift);
+            
+            // Horizontal line. 
+            if (descending) {
+                g.setColor(color.darker().darker());
+            } else {
+                g.setColor(color.brighter().brighter());
+            }
+            g.drawLine(dx, 0, 0, 0);
+
+            g.setColor(color);
+            g.translate(-x, -y);
+        }
+
+        public int getIconWidth() {
+            return size;
+        }
+
+        public int getIconHeight() {
+            return size;
+        }
+    }
+
+    private class SortableHeaderRenderer implements TableCellRenderer {
+        private TableCellRenderer tableCellRenderer;
+
+        public SortableHeaderRenderer(TableCellRenderer tableCellRenderer) {
+            this.tableCellRenderer = tableCellRenderer;
+        }
+
+        public Component getTableCellRendererComponent(JTable table, 
+                                                       Object value,
+                                                       boolean isSelected, 
+                                                       boolean hasFocus,
+                                                       int row, 
+                                                       int column) {
+            Component c = tableCellRenderer.getTableCellRendererComponent(table, 
+                    value, isSelected, hasFocus, row, column);
+            if (c instanceof JLabel) {
+                JLabel l = (JLabel) c;
+                l.setHorizontalTextPosition(JLabel.LEFT);
+                int modelColumn = table.convertColumnIndexToModel(column);
+                l.setIcon(getHeaderRendererIcon(modelColumn, l.getFont().getSize()));
+            }
+            return c;
+        }
+    }
+
+    private static class Directive {
+        private int column;
+        private int direction;
+
+        public Directive(int column, int direction) {
+            this.column = column;
+            this.direction = direction;
+        }
+    }
+}

+ 365 - 0
jplag.adminTool/src/main/java/jplagAdminTool/UserTableModel.java

@@ -0,0 +1,365 @@
+/*
+ * Created on 20.05.2005
+ * Author: Moritz Kroll
+ */
+package jplagAdminTool;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.Vector;
+
+import javax.swing.event.TableModelEvent;
+import javax.swing.table.AbstractTableModel;
+
+import jplagWsClient.jplagClient.UserData;
+import jplagWsClient.jplagClient.UserDataArray;
+
+public class UserTableModel extends AbstractTableModel {
+
+	private static final long serialVersionUID = 1L;
+    
+    private static final long MILLISECS_PER_DAY = 1000 * 60 * 60 * 24;
+	
+	public static final int USERNAME=0;
+	public static final int CREATED=1;
+	public static final int CREATEDBY=2;
+	public static final int EXPIRES=3;
+    public static final int DURATION=4;
+	public static final int LASTUSAGE=5;
+	public static final int NUMSUBS=6;
+	public static final int REALNAME=7;
+	public static final int EMAIL=8;
+	public static final int STATE=9;
+	
+	private int userstate=0;
+	
+	private String[] columnNames = { "Username", "Created", "CreatedBy",
+			"Expires", "Duration", "Last usage", "Subs", "Realname", "EMail", "State"};
+	
+	Vector<BackedUserData> userDataVector = null;
+	
+	public void setAdminState(int ustate) {
+		userstate=ustate;
+	}
+	
+	public int getAdminState() {
+		return userstate;
+	}
+
+	public int getColumnCount() {
+		return columnNames.length;
+	}
+
+	public int getRowCount() {
+		if(userDataVector == null) return 0;
+		return userDataVector.size();
+	}
+	
+	public String getColumnName(int col) {
+		return columnNames[col];
+	}
+    
+    @SuppressWarnings("unchecked")
+    public Class getColumnClass(int col) {
+        if(isDate(col)) return Date.class;
+        if(col==NUMSUBS || col==DURATION) return Integer.class;
+        return Object.class;
+    }
+	
+	public boolean isCellEditable(int row, int col) {
+        if(col == DURATION) return false;
+		if((userstate & BackedUserData.MASK_JPLAGADMIN)==0)
+		{
+			return col!=CREATED && col!=CREATEDBY && col!=LASTUSAGE &&
+				col!=NUMSUBS;
+		}
+		return true;
+	}
+
+    public boolean isDate(int col) {
+    	switch(col)
+    	{
+    		case CREATED:
+    		case EXPIRES:
+    		case LASTUSAGE:
+    			return true;
+    		default:
+    			return false;
+    	}
+    }
+
+	public static String formatCalendar(Calendar cal) {
+		if(cal==null) return "No date";
+		DateFormat df=DateFormat.getDateInstance(DateFormat.MEDIUM,Locale.GERMAN);
+		return df.format(cal.getTime());
+	}
+
+	/**
+	 * Accepts both dd.MM.yy and dd.MM.yyyy formats
+	 */
+    private Calendar parseCalendar(String string)
+			throws ParseException
+	{
+		Calendar cal=new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+		SimpleDateFormat sdf2=new SimpleDateFormat("dd.MM.yy");
+		SimpleDateFormat sdf4=new SimpleDateFormat("dd.MM.yyyy");
+		sdf2.setLenient(false);
+		sdf4.setLenient(false);
+		Date date;
+		try
+		{
+			date=sdf2.parse(string);
+		}
+		catch(ParseException e)
+		{
+			date=sdf4.parse(string);
+		}
+		cal.setTime(date);
+		return cal;
+	}
+    
+	public Object getValueAt(int row, int col) {
+		if(userDataVector==null || row>=userDataVector.size())
+			return "Illegal getValueAt call";
+		UserData ud=(UserData) userDataVector.get(row);
+		switch(col)
+		{
+			case USERNAME: return ud.getUsername();
+//			case CREATED: return formatCalendar(ud.getCreated());
+			case CREATED: return ud.getCreated().getTime();
+			case CREATEDBY: return ud.getCreatedBy();
+//			case EXPIRES: return formatCalendar(ud.getExpires());
+			case EXPIRES:
+				return (ud.getExpires()==null ? null
+											  : ud.getExpires().getTime());
+            case DURATION:
+                if(ud.getExpires() == null) return -1;
+                return (int)((ud.getExpires().getTimeInMillis()
+                        - ud.getCreated().getTimeInMillis()) / MILLISECS_PER_DAY);
+//			case LASTUSAGE: return formatCalendar(ud.getLastUsage());
+			case LASTUSAGE: 
+				return (ud.getLastUsage()==null ? null
+						  : ud.getLastUsage().getTime());
+			case NUMSUBS: return new Integer(ud.getNumOfSubs());
+			case REALNAME: return ud.getRealName();
+			case EMAIL: return ud.getEmail();
+			case STATE: return BackedUserData.getStateName(ud.getState());
+			default: return "Illegal column";
+		}
+	}
+	
+	public boolean isChanged(String orig,String newone) {
+		if((orig==null || orig.length()==0)!=(newone.length()==0)) return true;
+		if(orig==null || orig.length()==0) return false;
+		return !orig.equals(newone);
+	}
+	
+	public void setValueAt(Object val, int row, int col) {
+		if(userDataVector==null)
+		{
+			System.out.println("Illegal setValueAt call!");
+			return;
+		}
+		BackedUserData ud=(BackedUserData) userDataVector.get(row);
+		try {
+			boolean changed=false;
+			switch(col)
+			{
+				case USERNAME:
+					if(isChanged(ud.getUsername(),(String)val))
+					{
+						ud.setUsername((String)val);
+						changed=true;
+					}
+					break;
+				case CREATED:
+				{
+					Calendar newcal=parseCalendar((String)val);
+					if(ud.getCreated().after(newcal) ||
+							ud.getCreated().before(newcal))
+					{
+						ud.setCreated(newcal);
+						changed=true;
+					}
+					break;
+				}
+				case CREATEDBY:
+					if(isChanged(ud.getCreatedBy(),(String)val))
+					{
+						ud.setCreatedBy((String)val);
+						changed=true;
+					}
+					break;
+				case EXPIRES:
+					if(((String)val).equals(""))
+					{
+						if(ud.getExpires()!=null)
+						{
+							ud.setExpires(null);
+							changed=true;
+						}
+					}
+					else
+					{
+						Calendar newcal=parseCalendar((String)val);
+						if(ud.getExpires()==null
+								|| ud.getExpires().after(newcal)
+								|| ud.getExpires().before(newcal))
+						{
+							ud.setExpires(newcal);
+							changed=true;
+						}
+					}
+					break;
+				case LASTUSAGE:
+					if(((String)val).equals(""))
+					{
+						if(ud.getLastUsage()!=null)
+						{
+							ud.setLastUsage(null);
+							changed=true;
+						}
+					}
+					else
+					{
+						Calendar newcal=parseCalendar((String)val);
+						if(ud.getLastUsage().after(newcal) ||
+								ud.getLastUsage().before(newcal))
+						{
+							ud.setLastUsage(newcal);
+							changed=true;
+						}
+					}
+					break;
+				case NUMSUBS:
+				{
+					int newval=Integer.parseInt((String)val);
+					if(ud.getNumOfSubs()!=newval)
+					{
+						ud.setNumOfSubs(newval);
+						changed=true;
+					}
+					break;
+				}
+				case REALNAME:
+					if(isChanged(ud.getRealName(),(String) val))
+					{
+						ud.setRealName((String) val); 
+						changed=true;
+					}
+					break;
+				case EMAIL: 
+					if(isChanged(ud.getEmail(),(String) val))
+					{
+						ud.setEmail((String) val); 
+						changed=true;
+					}
+					break;
+				case STATE:
+				{
+					int newval=BackedUserData.getStateInt((String)val);
+					if(ud.getState()!=newval)
+					{
+						if((newval & BackedUserData.MASK_DEACTIVATED) == 0 && 
+								ud.getExpires()!=null)
+						{
+							Calendar cal=Calendar.getInstance(
+									TimeZone.getTimeZone("GMT"));
+							if(cal.after(ud.getExpires()))
+							{
+								if((ud.getState() & BackedUserData.MASK_EXPIRED) == 0)
+								{
+									ud.setState(ud.getState() | BackedUserData.MASK_EXPIRED);
+									changed=true;
+								}
+								break;
+							}
+						}
+						ud.setState(newval);
+						changed=true;
+					}
+					break;
+				}
+			}
+			if(changed)
+			{
+				fireTableChanged(new TableModelEvent(this,row,row,col));
+			}
+		}
+		catch(ParseException ex) {} // replace wrong cells by orginal ones
+		catch(NumberFormatException ex) {} // dito
+	}
+	
+	public boolean isValid(int row, int col) {
+		if(col==USERNAME || col==CREATEDBY || col==REALNAME || col==EMAIL)
+		{
+			Object obj=getValueAt(row,col);
+			if(obj==null || obj.toString().length()==0) return false;
+		}
+		return true;
+	}
+	
+	public void setUserDataArray(UserDataArray userarray) {
+		UserData[] dataArray=userarray.getItems();
+		userDataVector=new Vector<BackedUserData>(dataArray.length,3);
+		for(int i=0;i<dataArray.length;i++)
+		{
+			userDataVector.add(new BackedUserData(dataArray[i]));
+		}
+		fireTableDataChanged();
+	}
+	
+	public void addNewUser(UserData data) {
+		if(userDataVector==null)
+		{
+			System.out.println("addNewUser(UserData): userDataVector==null!!");
+			return;
+		}
+		BackedUserData bud=new BackedUserData(data);
+		userDataVector.add(bud);
+        fireTableDataChanged();
+	}
+
+	public void removeUser(String user) {
+		for(int i=0;i<userDataVector.size();i++)
+		{
+			if(((BackedUserData) userDataVector.get(i)).getOrigUsername().
+					equals(user)) {
+				userDataVector.remove(i);
+				fireTableRowsDeleted(i,i);
+				return;
+			}
+		}
+	}
+	
+	public boolean existsDoubled(String user) {
+		int numfound=0;
+		for(int i=0;i<userDataVector.size();i++)
+		{
+			if(((BackedUserData) userDataVector.get(i)).getUsername().
+					equals(user)) 
+				numfound++;
+		}
+		return numfound>=2;
+	}
+	
+	public int getUserState(String user) {
+		for(int i=0;i<userDataVector.size();i++)
+		{
+			BackedUserData data=(BackedUserData) userDataVector.get(i);
+			if(data.getUsername().equals(user)) 
+				return data.getState();
+		}
+		return 0;
+	}
+	
+	public BackedUserData getBackedUserData(int index) {
+		return (BackedUserData) userDataVector.get(index);
+	}
+}

BIN=BIN
jplag.adminTool/src/main/jnlp/resources/admintool.icon.ico


BIN=BIN
jplag.adminTool/src/main/jnlp/resources/admintool.splash.gif


+ 41 - 0
jplag.adminTool/src/main/jnlp/template.vm

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="$encoding"?>
+<jnlp spec="$jnlpspec" codebase="$jnlpCodebase" href="$outputFile">
+  <information>
+#if($project.Name)
+    <title>$project.Name</title>
+#end
+#if($project.Organization.Name)
+    <vendor>$project.Organization.Name</vendor>
+#end
+#if($project.Url)
+    <homepage href="$project.Url"/>
+#end
+#if($project.Description)
+    <description>$project.Description</description>
+#end
+#if($jnlpIcon32x32)
+    <icon kind="shortcut" href="$jnlpIcon32x32" width="32" height="32"/>
+#end
+#if($jnlpIcon64x64)
+    <icon href="$jnlpIcon64x64" width="64" height="64"/>
+    <icon kind="shortcut" href="$jnlpIcon64x64" width="64" height="64"/>
+#end
+#if($jnlpSplash)
+    <icon kind="splash" href="$jnlpSplash" />
+#end
+
+#if($offlineAllowed)
+    <offline-allowed/>
+#end
+  </information>
+#if($allPermissions)
+  <security>
+     <all-permissions/>
+  </security>
+#end
+  <resources>
+    <j2se version="$j2seVersion"/>
+     $dependencies
+  </resources>
+  <application-desc main-class="$mainClass"/>
+</jnlp>

+ 4 - 0
jplag.adminTool/src/main/resources/jplagAdminTool/version.properties

@@ -0,0 +1,4 @@
+# this is a filtered resource: the variables are being inserted during packaging!
+groupId=${project.groupId}
+artifactId=${project.artifactId}
+version=${project.version}

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio