/home/wpollock1/public_html/AJava/SafeInput.java

//package safehello;

import java.text.Normalizer;
import static java.text.Normalizer.Form.*;

import javafx.application.Application;
import javafx.event.*;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.text.*;
import javafx.stage.Stage;

/**
 * Main class for safe I18N coding practices, JavaFX demo.
 * This code shows (in a simple JavaFX GUI) how to normalize, sanitize,
 * and validate user input.
 *
 * @author Wayne Pollock, Tampa Florida USA
 */
public class SafeInput extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Safe I18N Coding Demo");

        // Use JavaFX Grid Layout:
        GridPane grid = new GridPane();
        grid.setAlignment(Pos.CENTER);
        grid.setHgap(10);
        grid.setVgap(24);
        grid.setPadding(new Insets(25, 25, 25, 25));
        Scene scene = new Scene(grid, 350, 275);
        primaryStage.setScene(scene);

        // Add components to the stage, via the layout object:
        Text title = new Text("Safe I18N Coding Demo");
        title.setFont(Font.font("sans-serif", FontWeight.NORMAL, 20));
        grid.add(title, 0, 0, 2, 1);

        Label userNameLbl = new Label("User Name:");
        grid.add(userNameLbl, 0, 1);


        final ComboBox<String> userName = new ComboBox<>();
        userName.getItems().addAll(
                "",
                "Joe-Bob Jr., 3rd.",
                "touch" + "\u00e9", // Accent
                "a" + "\ufb03" + "ance", // Ligature
                "fa" + "\u00e7" + "ade", // Cedilla
                "\uff81\uff6e\uff7a\uff9a\uff70\uff84", //half-width Katakana
                "<em>HTML</em>",  // illegal characters
                "Hubert Blaine Wolfeschlegelsteinhausenbergerdorff"
                );
        userName.setEditable(true);
        userName.setValue("");
        grid.add(userName, 1, 1);

        Text greeting = new Text();
        greeting.setFill(Color.BLACK);
        grid.add(greeting, 0, 3, 2, 1);

        Button btn = new Button( "Greet");
        btn.setDefaultButton(true);

        grid.add(btn, 1, 2);

        // Hook up event handling:
        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent e) {
                String name = nsv( userName.getValue().toString() );
                if ( name == null || name.length() == 0 ) {
                    greeting.setText("<no valid name selected>");
                } else {
                    greeting.setText("Howdy, " + name + "!");
                }
            }
        });

        // Make UI visible:
        primaryStage.show();
    }

    /**
     * nsv will Normalize Unicode, then Sanitize via a whitelist regular
     * expression, and finally validate the data (starts with a letter and
     * is less than 20 characters long.  The resulting String
     * (which may be empty) is returned.  In a secure context (user name
     * for login purposes), this method should throw an exception for bad
     * input, which should include an encoded (safe) version to include in
     * log messages.
     *
     * @param rawInput - The untrusted String
     * @return a normalized, sanitized, and validated String
     */
    public String nsv ( String rawInput ) {
        // Normalize Unicode first: use NFC; for identifiers (such as
        // user names for logins) and passwords, use NFKC:
        if ( ! Normalizer.isNormalized(rawInput, NFC) ) {
            rawInput = Normalizer.normalize(rawInput, NFC);
        }

        // Sanitize: Remove any illegal (not a letter, digit, dash, space,
        //           period, or comma) characters:
        String clean = rawInput.replaceAll("[^-\\p{Alnum} .,]", "");

        // Validate: Ensure userName has letters, and length is <20:
        if ( clean.length() > 20) {
            clean = clean.substring(0, 20);
        }
        if ( ! clean.matches("^\\p{Alpha}.*")) {
            clean = ""; // String should start with a letter
        }
        return clean;
    }
}