Monday, July 27, 2015

Java Numeric Formatting: DecimalFormat

In the post Java Numeric Formatting, I described and demonstrated some of the useful instances provided by NumberFormat static methods such as NumberFormat.getNumberInstance(Locale), NumberFormat.getPercentInstance(Locale), NumberFormat.getCurrencyInstance(Locale), and NumberFormat.getIntegerInstance(Locale). It turns out that all of these instances of abstract NumberFormat are actually instances of DecimalFormat, which extends NumberFormat.

The next code listing and the associated output demonstrate that all instances returned by NumberFormat's "getInstance" methods are actually DecimalFormat instances. What differentiates these instances of the same DecimalFormat class is the settings of their attributes such as minimum and maximum integer digits (digits to the left of the decimal point) and minimum and maximum number of fraction digits (digits to the right of the decimal point). They all share the same rounding mode and currency settings.

Instances Provided by NumberFormat.getInstance() Are DecimalFormat Instances
/**
 * Write characteristics of provided Currency object to
 * standard output.
 *
 * @param currency Instance of Currency whose attributes
 *    are to be written to standard output.
 */
public void printCurrencyCharacteristics(final Currency currency)
{
   out.print("\tCurrency: " + currency.getCurrencyCode() 
      + "(ISO 4217 Code: " + currency.getNumericCode() + "), ");
   out.println(currency.getSymbol() + ", (" + currency.getDisplayName() + ")");
}

/**
 * Writes characteristics of provided NumberFormat instance
 * to standard output under a heading that includes the provided
 * description.
 *
 * @param numberFormat Instance of NumberFormat whose key
 *    characteristics are to be written to standard output.
 * @param description Description to be included in standard
 *    output.
 */
public void printNumberFormatCharacteristics(
   final NumberFormat numberFormat, final String description)
{
   out.println(description + ": " + numberFormat.getClass().getCanonicalName());
   out.println("\tRounding Mode:           " + numberFormat.getRoundingMode());
   out.println("\tMinimum Fraction Digits: " + numberFormat.getMinimumFractionDigits());
   out.println("\tMaximum Fraction Digits: " + numberFormat.getMaximumFractionDigits());
   out.println("\tMinimum Integer Digits:  " + numberFormat.getMinimumIntegerDigits());
   out.println("\tMaximum Integer Digits:  " + numberFormat.getMaximumIntegerDigits());
   printCurrencyCharacteristics(numberFormat.getCurrency());
   if (numberFormat instanceof DecimalFormat)
   {
      final DecimalFormat decimalFormat = (DecimalFormat) numberFormat;
      out.println("\tPattern: " + decimalFormat.toPattern());
   }
}

/**
 * Display key characteristics of the "standard"
 * NumberFormat/DecimalFormat instances returned by the static
 * NumberFormat methods getIntegerInstance(), getCurrencyInstance(),
 * getPercentInstance(), and getNumberInstance().
 */
public void demonstrateDecimalFormatInstancesFromStaticNumberFormatMethods()
{
   final NumberFormat integerInstance = NumberFormat.getIntegerInstance();
   printNumberFormatCharacteristics(integerInstance, "IntegerInstance");
   final NumberFormat currencyInstance = NumberFormat.getCurrencyInstance();
   printNumberFormatCharacteristics(currencyInstance, "CurrencyInstance");
   final NumberFormat percentInstance = NumberFormat.getPercentInstance();
   printNumberFormatCharacteristics(percentInstance, "PercentInstance");
   final NumberFormat numberInstance = NumberFormat.getNumberInstance();
   printNumberFormatCharacteristics(numberInstance, "NumberInstance");
}

Although my previous post and this post so far have demonstrated obtaining instances of DecimalFormat via static NumberFormat access methods, DecimalFormat also has three overloaded constructors DecimalFormat(), DecimalFormat(String), and DecimalFormat(String, DecimalFormatSymbols). Note, however, that there is a warning in DecimalFormat's Javadoc documentation stating, "In general, do not call the DecimalFormat constructors directly, since the NumberFormat factory methods may return subclasses other than DecimalFormat." My next few examples do instantiate DecimalFormat instances with their direct constructors despite that Javadoc warning because there is no harm in this case of doing so.

Instances of DecimalFormat support a great degree of control over the presentation formatting of decimal numbers. The following code runs the standard set of numbers used in the earlier example against a variety of different custom patterns. The screen snapshot after the code listing shows how these numbers are rendered when these patterns are applied.

/**
 * Apply provided pattern to DecimalFormat instance and write
 * output of application of that DecimalFormat instance to
 * standard output along with the provided description.
 *
 * @param pattern Pattern to be applied to DecimalFormat instance.
 * @param description Description of pattern being applied.
 */
private void applyPatternToStandardSample(
   final String pattern, final String description)
{
   final DecimalFormat decimalFormat = new DecimalFormat(pattern);
   printHeader(description + " - Applying Pattern '" + pattern + "'");
   for (final double theDouble : ourStandardSample)
   {
      out.println(
         theDouble + ": " + decimalFormat.format(theDouble));
   }
}

/**
 * Demonstrate various String-based patters applied to
 * instances of DecimalFormat.
 */
public void demonstrateDecimalFormatPatternStringConstructor()
{
   final String sixFixedDigitsPattern = "000000";
   applyPatternToStandardSample(sixFixedDigitsPattern, "Six Fixed Digits");
   final String sixDigitsPattern = "###000";
   applyPatternToStandardSample(sixDigitsPattern, "Six Digits Leading Zeros Not Displayed");
   final String percentagePattern = "";
   applyPatternToStandardSample(percentagePattern, "Percentage");
   final String millePattern = "\u203000";
   applyPatternToStandardSample(millePattern, "Mille");
   final String currencyPattern = "\u00A4";
   applyPatternToStandardSample(currencyPattern, "Currency");
   final String internationalCurrencyPattern = "\u00A4";
   applyPatternToStandardSample(internationalCurrencyPattern, "Double Currency");
   final String scientificNotationPattern = "0.###E0";
   applyPatternToStandardSample(scientificNotationPattern, "Scientific Notation");
}
==================================================================
= Six Fixed Digits - Applying Pattern '000000'
==================================================================
NaN: �
0.25: 000000
0.4: 000000
0.567: 000001
1.0: 000001
10.0: 000010
100.0: 000100
1000.0: 001000
10000.0: 010000
100000.0: 100000
1000000.0: 1000000
1.0E7: 10000000
Infinity: ∞
==================================================================
= Six Digits Leading Zeros Not Displayed - Applying Pattern '###000'
==================================================================
NaN: �
0.25: 000
0.4: 000
0.567: 001
1.0: 001
10.0: 010
100.0: 100
1000.0: 1000
10000.0: 10000
100000.0: 100000
1000000.0: 1000000
1.0E7: 10000000
Infinity: ∞
==================================================================
= Percentage - Applying Pattern ''
==================================================================
NaN: �
0.25: %25
0.4: %40
0.567: %57
1.0: %100
10.0: %1000
100.0: %10000
1000.0: %100000
10000.0: %1000000
100000.0: %10000000
1000000.0: %100000000
1.0E7: %1000000000
Infinity: %∞
==================================================================
= Mille - Applying Pattern '‰00'
==================================================================
NaN: �
0.25: ‰250
0.4: ‰400
0.567: ‰567
1.0: ‰1000
10.0: ‰10000
100.0: ‰100000
1000.0: ‰1000000
10000.0: ‰10000000
100000.0: ‰100000000
1000000.0: ‰1000000000
1.0E7: ‰10000000000
Infinity: ‰∞
==================================================================
= Currency - Applying Pattern '¤'
==================================================================
NaN: �
0.25: $0
0.4: $0
0.567: $1
1.0: $1
10.0: $10
100.0: $100
1000.0: $1000
10000.0: $10000
100000.0: $100000
1000000.0: $1000000
1.0E7: $10000000
Infinity: $∞
==================================================================
= Double Currency - Applying Pattern '¤'
==================================================================
NaN: �
0.25: $0
0.4: $0
0.567: $1
1.0: $1
10.0: $10
100.0: $100
1000.0: $1000
10000.0: $10000
100000.0: $100000
1000000.0: $1000000
1.0E7: $10000000
Infinity: $∞
==================================================================
= Scientific Notation - Applying Pattern '0.###E0'
==================================================================
NaN: �
0.25: 2.5E-1
0.4: 4E-1
0.567: 5.67E-1
1.0: 1E0
10.0: 1E1
100.0: 1E2
1000.0: 1E3
10000.0: 1E4
100000.0: 1E5
1000000.0: 1E6
1.0E7: 1E7
Infinity: ∞

For my last two examples of applying DecimalFormat, I will acquire the instance of DecimalFormat via the preferred approach of using NumberFormat.getInstance(Locale). The first code listing demonstrates different locales applied to the same double and then the output format from each.

/**
 * Provides an instance of DecimalFormat based on the provided instance
 * of Locale.
 *
 * @param locale Locale to be associated with provided instance of
 *    DecimalFormat.
 * @return Instance of DecimalFormat associated with provided Locale.
 * @throws ClassCastException Thrown if the object provided to me
 *    by NumberFormat.getCurrencyInstance(Locale) is NOT an instance
 *    of class {@link java.text.DecimalFormat}.
 */
private DecimalFormat getDecimalFormatWithSpecifiedLocale(final Locale locale)
{
   final NumberFormat numberFormat = NumberFormat.getCurrencyInstance(locale);
   if (!(numberFormat instanceof DecimalFormat))
   {
      throw new ClassCastException(
         "NumberFormat.getCurrencyInstance(Locale) returned an object of type "
            + numberFormat.getClass().getCanonicalName() + " instead of DecimalFormat.");
   }
   return (DecimalFormat) numberFormat;
}

/**
 * Demonstrate formatting of double with various Locales.
 */
public void demonstrateDifferentLocalesCurrencies()
{
   final double monetaryAmount = 14.99;
   out.println("Locale-specific currency representations of " + monetaryAmount + ":");
   out.println("\tLocale.US:            "
      + getDecimalFormatWithSpecifiedLocale(Locale.US).format(monetaryAmount));
   out.println("\tLocale.UK:            "
      + getDecimalFormatWithSpecifiedLocale(Locale.UK).format(monetaryAmount));
   out.println("\tLocale.ENGLISH:       "
      + getDecimalFormatWithSpecifiedLocale(Locale.ENGLISH).format(monetaryAmount));
   out.println("\tLocale.JAPAN:         "
      + getDecimalFormatWithSpecifiedLocale(Locale.JAPAN).format(monetaryAmount));
   out.println("\tLocale.GERMANY:       "
      + getDecimalFormatWithSpecifiedLocale(Locale.GERMANY).format(monetaryAmount));
   out.println("\tLocale.CANADA:        "
      + getDecimalFormatWithSpecifiedLocale(Locale.CANADA).format(monetaryAmount));
   out.println("\tLocale.CANADA_FRENCH: "
      + getDecimalFormatWithSpecifiedLocale(Locale.CANADA_FRENCH).format(monetaryAmount));
   out.println("\tLocale.ITALY:         "
      + getDecimalFormatWithSpecifiedLocale(Locale.ITALY).format(monetaryAmount));
}
Locale-specific currency representations of 14.99:
 Locale.US:            $14.99
 Locale.UK:            £14.99
 Locale.ENGLISH:       ¤14.99
 Locale.JAPAN:         ¥15
 Locale.GERMANY:       14,99 €
 Locale.CANADA:        $14.99
 Locale.CANADA_FRENCH: 14,99 $
 Locale.ITALY:         € 14,99

My DecimalFormat examples so far have focused on formatting numbers for presentation. This final example goes the other direction and parses a value from the string representation.

/**
 * Demonstrate parsing.
 */
public void demonstrateParsing()
{
   final NumberFormat numberFormat = NumberFormat.getCurrencyInstance(Locale.US);
   final double value = 23.23;
   final String currencyRepresentation = numberFormat.format(value);
   out.println("Currency representation of " + value + " is " + currencyRepresentation);
   try
   {
      final Number parsedValue = numberFormat.parse(currencyRepresentation);
      out.println("Parsed value of currency representation " + currencyRepresentation + " is " + parsedValue);
   }
   catch (ParseException parseException)
   {
      out.println("Exception parsing " + currencyRepresentation + parseException);
   }
}
Currency representation of 23.23 is $23.23
Parsed value of currency representation $23.23 is 23.23

The last example shown did not actually need to access the concrete DecimalNumber methods and was able to solely use the NumberFormat-advertised methods. The example formats a currency representation with NumberFormat.format(double) and then parses that provided currency representation to return to the original value with NumberFormat.parse(String).

NumberFormat, and more specifically DoubleFormat, "format and parse numbers for any locale."

Monday, July 20, 2015

Using Hibernate Bean Validator in Java SE

The main Bean Validation page states that "Bean Validation is a Java specification which ... runs in Java SE but is integrated in Java EE (6 and 7)." This post demonstrates using Java Bean Validation reference implementation (Hibernate Validator) outside of a Java EE container. The examples in this post are based on Hibernate Validator 5.1.3 Final, which can be downloaded at http://hibernate.org/validator/downloads.

"Getting Started with Hibernate Validator" states that Hibernate Validator requires implementations of Unified Expression Language (JSR 341) and Contexts and Dependency Injection (CDI/JSR 346). Implementations of these specifications are available in modern Java EE compliant containers (application servers), but use of Hibernate Validator in Java SE environments requires procurement and use of separate implementations.

The "Getting Started with Hibernate Validator" page provides the Maven XML one can use to identify dependencies on the Expression Language API (I'm using Expression Language 3.0 API), Expression Language Implementation (I'm using Expression Language Implementation 2.2.6), and Hibernate Validator CDI portable extension (I'm using Hibernate Validator Portable Extension 5.1.3 Final). I am also using Bean Validation API 1.1.0 Final, JBoss Logging 3.3.0 Final, and ClassMate 1.2.0 to build and run my examples.

There are three Java classes defined for the examples of bean validation demonstrated in this post. One class, Car.java is adapted from the example provided on the "Getting started with Hibernate Validator" page and its code listing is shown next.

Car.java
package dustin.examples;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

/**
 * Example adapted from "Getting Started with Hibernate Validator"
 * (http://hibernate.org/validator/documentation/getting-started/).
 */
public class Car
{
   @NotNull
   private String manufacturer;

   @NotNull
   @Size(min = 2, max = 14)
   private String licensePlate;

   @Min(2)
   private int seatCount;

   public Car(final String manufacturer, final String licencePlate, final int seatCount)
   {
      this.manufacturer = manufacturer;
      this.licensePlate = licencePlate;
      this.seatCount = seatCount;
   }

   public String getManufacturer()
   {
      return manufacturer;
   }

   public String getLicensePlate()
   {
      return licensePlate;
   }

   public int getSeatCount()
   {
      return seatCount;
   }

   @Override
   public String toString()
   {
      return "Car{" +
         "manufacturer='" + manufacturer + '\'' +
         ", licensePlate='" + licensePlate + '\'' +
         ", seatCount=" + seatCount +
         '}';
   }
}

Another class used in this post's examples is defined in Garage.java and is mostly a wrapper of multiple instances of Car. Its primary purpose is to help illustrate recursive validation supported by Hibernate Bean Validator.

Garage.java
package dustin.examples;

import javax.validation.Valid;
import javax.validation.constraints.Size;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
 * Holds cars.
 */
public class Garage
{
   @Size(min = 1)
   @Valid
   private final Set<Car> cars = new HashSet<>();

   public Garage() {}

   public void addCar(final Car newCar)
   {
      cars.add(newCar);
   }

   public Set<Car> getCars()
   {
      return Collections.unmodifiableSet(this.cars);
   }
}

The Garage code listing above uses the @Valid annotation to indicate that the Car instances held by the class should also be validated ("validation cascading").

The final Java class used in this post's examples is the class that will actually perform the validation of the two bean validation annotated classes Car and Garage. This class's listing is shown next.

HibernateValidatorDemonstration.java
package dustin.examples;

import static java.lang.System.out;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
import javax.validation.Validator;
import java.util.Set;

/**
 * Demonstrate use of Hibernate Validator.
 */
public class HibernateValidatorDemonstration
{
   private final Validator validator;

   public HibernateValidatorDemonstration()
   {
      final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
      validator = factory.getValidator();
   }

   public void demonstrateValidator()
   {
      final Car nullManufacturerCar = new Car(null, "ABC123", 4);
      final Set<ConstraintViolation<Car>> nullMfgViolations = validator.validate(nullManufacturerCar);
      printConstraintViolationsToStandardOutput("Null Manufacturer Example", nullMfgViolations);

      final Car nullLicenseCar = new Car("Honda", null, 3);
      final Set<ConstraintViolation<Car>> nullLicenseViolations = validator.validate(nullLicenseCar);
      printConstraintViolationsToStandardOutput("Null License Example", nullLicenseViolations);

      final Car oneSeatCar = new Car("Toyota", "123ABC", 1);
      final Set<ConstraintViolation<Car>> tooFewSeatsViolations = validator.validate(oneSeatCar);
      printConstraintViolationsToStandardOutput("Too Few Seats Example", tooFewSeatsViolations);

      final Car oneDigitLicenseCar = new Car("General Motors", "I", 2);
      final Set<ConstraintViolation<Car>> tooFewLicenseDigitsViolation = validator.validate(oneDigitLicenseCar);
      printConstraintViolationsToStandardOutput("Too Few License Digits Example", tooFewLicenseDigitsViolation);

      final Car nullManufacturerNullLicenseCar = new Car(null, null, 4);
      final Set<ConstraintViolation<Car>> nullMfgLicenseViolation = validator.validate(nullManufacturerNullLicenseCar);
      printConstraintViolationsToStandardOutput("Null Manufacturer and Null License Example", nullMfgLicenseViolation);

      final Garage garage = new Garage();
      final Set<ConstraintViolation<Garage>> noCarsInGarage = validator.validate(garage);
      printConstraintViolationsToStandardOutput("No Cars in Garage", noCarsInGarage);

      garage.addCar(oneDigitLicenseCar);
      garage.addCar(oneSeatCar);
      garage.addCar(nullManufacturerNullLicenseCar);
      final Set<ConstraintViolation<Garage>> messedUpCarsInGarage = validator.validate(garage);
      printConstraintViolationsToStandardOutput("Messed Up Cars in Garage", messedUpCarsInGarage);
   }

   private <T> void printConstraintViolationsToStandardOutput(
      final String title,
      final Set<ConstraintViolation<T>> violations)
   {
      out.println(title);
      for (final ConstraintViolation<T> violation : violations)
      {
         out.println("\t" + violation.getPropertyPath() + " " + violation.getMessage());
      }
   }

   public static void main(final String[] arguments)
   {
      final HibernateValidatorDemonstration instance = new HibernateValidatorDemonstration();
      instance.demonstrateValidator();
   }
}

The above code features several calls to javax.validation.Validator.validate(T, Class<?>) that demonstrate the effectiveness of the annotations on the classes whose instances are being validated. Several examples validate an object's single validation violation, an example validates an object's multiple validation violations, and a final example demonstrates successful cascading violation detection.

The class HibernateValidatorDemonstration has a main(String[]) function that can be executed in a Java SE environment (assuming the necessary JARs are on the runtime classpath). The output of running the above demonstration class is shown next:

Jul 19, 2015 9:30:05 PM org.hibernate.validator.internal.util.Version 
INFO: HV000001: Hibernate Validator 5.1.3.Final
Null Manufacturer Example
 manufacturer may not be null
Null License Example
 licensePlate may not be null
Too Few Seats Example
 seatCount must be greater than or equal to 2
Too Few License Digits Example
 licensePlate size must be between 2 and 14
Null Manufacturer and Null License Example
 manufacturer may not be null
 licensePlate may not be null
No Cars in Garage
 cars size must be between 1 and 2147483647
Messed Up Cars in Garage
 cars[].licensePlate size must be between 2 and 14
 cars[].manufacturer may not be null
 cars[].licensePlate may not be null
 cars[].seatCount must be greater than or equal to 2

Conclusion

This post has demonstrated that the Hibernate Bean Validator, the reference implementation of the Bean Validation specification, can be executed in a Java SE environment. As part of this demonstration, some basic concepts associated with the Bean Validation specification and the Hibernate Bean Validator implementation were also discussed and demonstrated.

Additional Resources

Friday, July 17, 2015

Packt Publishing's Skill Up Promotion

Packt Publishing is currently running a "Skill Up" promotion with the tagline, "Learn More to Earn More." There are three separate special offers associated with the Skill Up promotion. One option is to purchase any e-book or video for $10 (USD). Another option is to select a "bundle" of five e-books for a total of $25 (USD) for that bundle ($5 per book). The third option is one year's access to PacktLib for $80 (USD).

The "bundle" offer (five e-books for $25 USD) appears to apply to any five e-books or videos in Packt Publishing's large catalog. However, there are several pre-selected bundles ("tech playlists") available for developers wishing to purchase these books in one category. For example, here are some of the available pre-selected bundles:

These are several more pre-selected bundles available than those shown above, but I created and purchased my own "tech playlist" with a PostgreSQL database theme:

The "list" prices for the above five PostgreSQL books would have totaled over $140. It was nice to pay only $25 for all five of them.

As part of the "Skill Up" promotion, reports on developers' salaries are available. The purpose of these appears to be for developers to determine the salary ranges associated with certain types of skills and then, in theory, a developer could purchase e-books and videos on those topics of interest (and associated with promising salaries) to learn those skills.

The "Skill Up" promotion appears to have just started, but I don't know when the "Skill Up" promotion ends.

Tuesday, July 14, 2015

Book Review: JavaScript Regular Expressions

Loiane Groner's and Gabriel Manricks's book JavaScript Regular Expressions (Packt Publishing, May 2015) has the subtitle, "Leverage the power of regular expressions to create an engaging user experience." The book is relatively short with five chapters a preface, and an appendix spanning approximately 90 substantive pages.

Preface

The preface provides a sentence of two describing each of JavaScript Regular Expressions's five chapters and its appendix. The preface explains that a text editor and web browser are all that are needed for most of the book's examples, but states that Node.js is required for Chapter 5's examples. The preface also states that the book is intended "for JavaScript developers who work with any type of user entry data" and "for JavaScript programmers who possess basic to intermediate skills in JavaScript regular expressions, and want to learn about these for the first time or sharpen their skills to become experts."

Chapter 1: Getting Started with Regex

The first chapter of JavaScript Regular Expressions introduces regular expressions (regex) by covering the idea behind regular expressions from a conceptual perspective. It then moves onto trying out regular expressions in JavaScript and specifically mentions using a browser's JavaScript console to try them out. The RegExp constructor is introduced.

A section in Chapter 1 introduces pattern flags as ignore case (i), multiline (m), and global match (g). Another section describes using RegExp functions test() and exec() and using String functions replace(), search, and match.

Chapter 1 concludes with a simple web form example for testing regular expressions examples that is built on HTML, JavaScript, Cascading Style Sheets, Bootstrap, and jQuery. This example does a nice job of illustrating the basic functions of RegExp discussed earlier in the chapter and at the same time provides a handy tool for testing regular expressions.

Chapter 2: The Basics

JavaScript Regular Expressions's second chapter introduces "vague matchers" and multipliers. The section on "vague matchers" introduces the regular expressions metadata/character characters such as dot (period or "wildcard character"), digit (\d), word (\w), and negated forms (\D and \W). It also explains and demonstrates specifying ranges, escaping hyphen, and negating ranges.

The "multipliers" section of the second chapter introduces the standard multipliers: + (one or more), * (zero or more), and ? (zero or one). The chapter then describes and illustrates more customizable multipliers using curly brace syntax. Chapter 2 also introduces the regular expression pipe (alternation).

Chapter 3: Special Characters

The third chapter covers "more advanced techniques" associated with regular expressions: boundaries, nongreedy quantifiers, and groups. The chapter introduces "nonvisual constraints" such as the anchors caret (^) for indicating the start of a line and dollar sign ($) for indicating the end of a line. Other early chapter discussions involve matching word boundaries (\b), matching non-word boundaries (\B), and matching whitespace (\s). Chapter 3's section on nongreedy quantifiers explains how to use the question mark (?) to specify "ungreedy quantifiers."

Chapter 3's examples for applying groups move back to using the web browser's JavaScript console instead of the example HTML application presented in the initial chapter. This section demonstrates applying groups in regular expressions in JavaScript code and introduces capture groups, noncapture groups (?:), back references, lookahead groups (?=), and negative lookahead (?!).

Chapter 4: Regex in Practice

JavaScript Regular Expression's fourth chapter provides "some actual use cases" to illustrate "some common design patterns" in crafting regular expressions. The chapter provides an example of building a form with JavaScript code (including regular expression handling) used for parsing and validating the form input. The example is constructed step-by-step with text explanations of each code listing. The specific portions of the form that are illustrated are name validation, e-mail validation, Twitter username validation, password validation, URL validation, text validation, and text manipulation (including a Markdown example).

Chapter 5: Node.js and Regex

The final chapter of JavaScript Regular Expressions explains "how to implement a simple Node.js application that reads a log file and parses it using a regular expression." The chapter begins by explaining how to download Node.js and recommending that those new to Node.js review the tutorials at https://nodejs.org/. After discussing how to verify that Node.js is installed correctly, the chapter looks at "reading a file with Node.js." It describes configuring Node.js to work with the file system and explains the anatomy of an Apache log file.

Chapter 5 provides a detailed discussion regarding the construction of regular expressions for parsing the Apache log file. An interesting twist presented in the chapter is representing each Apache log row in JavaScript Object Notation (JSON). There is then an example of presenting this JSON in an HTML table.

Appendix: JavaScript Regex Cheat Sheet

JavaScript Regular Expressions's appendix is just over 6 pages that consist of tables presenting columns with patterns, descriptions, and examples for various types of regular expressions including character classes, character sets, literals, boundaries, alternation, grouping, back reference, and quantifiers. The final table in the appendix is in the section "JavaScript regular expressions methods" and this table displays patterns, descriptions, and examples of JavaScript methods (mostly on String and RegExp) that are "used to match or test a regular expression."

General Observations

  • JavaScript Regular Expressions provides a nice introduction to applying regular expressions in JavaScript and is a quick read with fewer than 100 pages.
    • The significant general coverage of regular expressions is likely to be useful to anyone new to regular expressions in any programming language, but the book does discuss integrating regular expressions with JavaScript code and using JavaScript's particular flavor of regular expressions.
    • Only basic familiarity with JavaScript is required to benefit from the book.
    • JavaScript developers who are already comfortable with regular expressions will probably find less new material in the book, though I did learn some things from reading it even though I'm fairly comfortable with regular expressions and JavaScript.
  • The electronic version (PDF) of JavaScript Regular Expressions that I reviewed includes color screen snapshots.
  • Code listings in JavaScript Regular Expressions are black font on white background with no line numbers and no color syntax.
  • The examples in JavaScript Regular Expressions are generally short and easy to follow and are generally described in detail. I particularly liked the example of the regular expression testing web page and the example of building an HTML form with regular expression based validation.
  • The appendix of JavaScript Regular Expressions provides a concise reference of the most important aspects of regular expressions.

Conclusion

JavaScript Regular Expressions packs a lot into a relatively small book that is easy to read. The examples are basic and of small enough size to be easy to digest. The book contains lots of practical advice and would be especially beneficial to someone with basic familiarity with JavaScript but little or no knowledge of regular expressions. The book could also benefit someone wanting to learn basics of regular expressions even in languages other than JavaScript as the book covers regular expressions in a general way more often than it covers regular expressions in a JavaScript-specific way.

Tuesday, July 7, 2015

Book Review: Object-Oriented JavaScript, Second Edition

The Second Edition of “Object-Oriented JavaScript” (Packt Publishing, 2013) provides an excellent introduction to JavaScript and using JavaScript objects. The book, written by Stoyan Stefanov and Kumar Chetan Sharma, has the subtitle, “Learn everything you need to know about OOJS in this comprehensive guide.” This is a review of the Second Edition of Object-Oriented JavaScript, a book that features eight chapters spanning almost 300 pages and four appendices spanning nearly 50 pages.

Preface

The Preface of Object-Oriented JavaScript states that the book is for "anyone who is starting to learn JavaScript or who knows JavaScript but isn't very good at the object-oriented part of it." The Preface also states that readers need access to a modern web browser, text editor, and optional Node.js setup.

Chapter 1: Object-oriented JavaScript

The initial chapter of Object-Oriented JavaScript provides an overview of JavaScript, a brief summary of the history of JavaScript, a description of the current state of JavaScript, and some speculation on the future of JavaScript.

Chapter 1's coverage of ECMAScript 5 describes strict mode and the section on object-oriented programming introduces basic object-oriented concepts such as objects, classes, inheritance, encapsulation, aggregation, and polymorphism.

Chapter 1 ends with a discussion of "setting up your training environment" that introduces WebKit's Web Inspector, JavaScriptCore on the Mac, and consoles on different web browsers.

Chapter 2: Primitive Data Types, Arrays, Loops, and Conditions

Object-Oriented JavaScript's second chapter introduces the basics of JavaScript such as variables and data types, operators, comparisons, arrays, conditions, loops, switch statement, and comments. The chapter consists of 40+ pages and provides a nice introduction to JavaScript basics that should be approachable even for those relatively new to JavaScript.

Chapter 3: Functions

The third chapter of Object-Oriented JavaScript opens with a nice summary of the significance of functions in JavaScript:

Mastering functions is an important skill when you learn any programming language, and even more so when it comes to JavaScript. This is because JavaScript has many uses for functions, and much of the language's flexibility and expressiveness comes from them. Where most programming languages have a special syntax for some object-oriented features, JavaScript just uses functions.

Chapter 3's coverage of JavaScript functions introduces the basic syntax of a JavaScript function, how to write a function, and how to invoke a function. There is also a section of the chapter on predefined JavaScript functions such as parseInt(), parseFloat(), isNaN(), isFinite(), encodeURI(), decodeURI(), encodeURIComponent(), decodeURIComponent(), eval(), and the non-standard alert().

Object-Oriented JavaScript's third chapter takes on one of JavaScript's trickiest areas: variable scope. It differentiates between "global" and "local" variables and describes variable hoisting. The chapter also introduces anonymous functions (including callback functions and immediate functions). The chapter concludes with coverage of JavaScript closures.

Chapter 4: Objects

The first three chapters of Object-Oriented JavaScript focus mostly on basic JavaScript with a little bit of focus on objects and object-oriented concepts in the first chapter. However, there is no significant discussion specific to the combination of the two (use of objects in JavaScript) until the fourth chapter. This chapter focuses on objects in JavaScript and begins by comparing and contrasting JavaScript objects to JavaScript arrays.

Chapter 4 of describes the two ways of accessing JavaScript object properties (square bracket notation and dot notation) before introducing constructor functions, use of the 'this' keyword, use of the 'instanceof' operator, comparing JavaScript objects, and passing objects to and returning objects from JavaScript functions.

The section of the fourth chapter on "objects in the WebKit console" demonstrates use of the WebKit console to view all of a JavaScript object's properties and use of console.log() and console.error() to view any desired JavaScript values. A section of Chapter 4 also focuses on built-in JavaScript objects Object, Array, Function, Boolean, Number, String, Math, Date, RegExp, and Error objects. The book features an appendix (Appendix C) with more details on more built-in objects.

Chapter 5: Prototype

The prototype property is the subject of the fifth chapter of Object-Oriented JavaScript. The chapter introduces and explains how the prototype property works and differentiates between "own properties" and "prototype properties." The chapter discusses enumerating an object's properties using a JavaScript for-in loop, Object.prototype.propertyIsEnumerable(), and Object.prototype.hasOwnProperty(). The chapter also describes Object.prototype.isPrototypeOf() and the "secret" __proto__ property.

The chapter's section "Augmenting built-in objects" describes adding new methods to built-in constructor functions. A sub-section also cautions about the use of this feature with some of the same arguments I discussed in the blog post A Java Developer's Perspective on the Power and Danger of JavaScript's Object Prototype. The chapter concludes with two "prototype gotchas."

Chapter 6: Inheritance

The sixth chapter of Object-Oriented JavaScript looks at "common patterns for implementing inheritance" in JavaScript. It discusses prototype chaining, copying prototypes, adding a constructor call, creating a so-called uber function to allow a child object to access its parent object, and encapsulating inheritance logic in an "extends" function.

A section in Chapter 6 discusses "inheritance" via "copy[ing] the properties you like from one object to another." It covers shallow copy and deep copy approaches as well as use of a custom object() function that "accepts an object and returns a new one that has the parent as a prototype" (prototypal inheritance/Object.create()). Other items related to inheritance discussed in this chapter include multiple inheritance, mixins, parasitic inheritance, and borrowing a constructor.

Chapter 6 ends with a table comparing the different approaches to JavaScript inheritance covered in the chapter. There is also analysis provided as an illustration of how to decide which approach is most suitable for different situations.

Chapter 7: The Browser Environment

Chapter 7 focuses on the historically most common deployment environment for JavaScript: the web browser. The chapter begins by demonstrating inclusion of JavaScript in an HTML page via external file and via direct embedding in the HTML. The chapter then introduces the W3C standard Document Object Model (DOM) and non-standard Browser Object Model (BOM), compares and contrasts them briefly, and dives into more details on each.

In another example of how Object-Oriented JavaScript provides introductory JavaScript details that are not necessarily specific to objects, the seventh chapter explains why feature sniffing (or capability detection) is generally preferred over browser detection. The chapter also uses illustrations and text to explain how the browser console can be used as "a cheat sheet" to "inspect [the BOM and DOM properties] in an object."

Several of the properties of the window object are introduced and briefly described in Chapter 7: window.location, window.history, window.frames, window.screen, window.open(), window.close(), window.moveTo(), window.resizeTo(), window.alert(), window.prompt(), window.confirm(), window.setTimeout(), window.setInterval(), and window.document. A section of the chapter explains the DOM and how to traverse it and style (CSS) elements on it.

Chapter 7 presents significant coverage of event handling and Ajax/XMLHttpRequest. Chapter 7, like Chapter 2 and Chapter 3 and most of Chapter 1, covers JavaScript in general rather than particularly focusing on objects in JavaScript. I found it interesting and a positive aspect of this book that only one chapter focused on JavaScript in the web browser and the remainder of the book treated JavaScript more generally.

Chapter 8: Coding and Design Patterns

The final chapter of the book introduces "coding patterns" (described in the chapter as "JavaScript-specific best practices") and "design patterns" (described in the chapter as "language-independent patterns, popularized by the famous 'Gang of Four' book"). The portion of the chapter covering "coding patterns" (or "best practices") discusses several ideas for improving one's JavaScript. Some of the items covered in this section include a very brief introduction to JSON, immediate functions, using modules, using namespaces, and separating behavior from content and presentation.

The second portion of Chapter 8 introduces design patterns as popularized by the book Design Patterns: Elements of Reusable Object-Oriented Software and covers four of the 23 patterns presented in that C++-oriented book from a JavaScript perspective. The four patterns covered in Object-Oriented JavaScript are Singleton, Factory, Decorator, and Observer.

The Appendices

A significant portion of Object-Oriented JavaScript is presented as four appendices. The appendices cover reserved words in JavaScript (keywords reserved for current use, keywords reserved for future use, and keywords that used to be but are no longer reserved), built-in JavaScript functions, built-in objects, and regular expressions in JavaScript. These appendices are presented largely in tabular format that makes them especially conducive as references. The chapters cover many of the same topics in more explanatory text and then the appendices provide quick reference on details associated with many of these topics.

General Observations

  • Most of the first chapter, Chapter 2, Chapter 3, Chapter 7, and half of Chapter 8 cover JavaScript in general rather than focusing on JavaScript objects. These chapters (or the first half of the chapter in the case of Chapter 8) could probably be skipped by developers familiar with the basics of JavaScript syntax who are mainly interested in learning specifically about using objects in JavaScript. For those who have little or no JavaScript experience, these chapters provide adequate introductory material that likely precludes the need of using any other introductory JavaScript book or resource before reading this book.
  • The chapters in Object-Oriented JavaScript tend to be explanatory text with illustrations while the appendices more concisely represent some of the same topics covered in the chapters in a reference format.
  • The PDF version of Object-Oriented JavaScript that I reviewed featured high-resolution color screen snapshots that helped illustrate points being made.
  • Code listings, even in the electronic edition I reviewed, are black text on white background with no line numbers and no color syntax.

Conclusion

Object-Oriented JavaScript (Second Edition) is a well-written book that thoroughly introduces object-oriented JavaScript, but also introduces many other basic JavaScript concepts and syntax. A reader with little or no familiarity with JavaScript is likely to gain much from this book because it has so many introductory JavaScript concepts covered in it. Even readers who have some experience and familiarity with basic JavaScript principles are likely to find the book helpful (especially chapters 4 through 6) for gaining a deeper understanding of JavaScript's take on object-oriented programming and application of JavaScript's prototype object.

Thursday, July 2, 2015

Windows Registry Cleanup after JDK 9 Early Release Installation

In my last blog post, I demonstrated resolution of issues surrounding the Oracle Java symbolic links (C:\ProgramData\Oracle\Java\javapath\ directory on Windows-based machines) after I had installed an early release of JDK 9 (build 68) that seemed to prevent automatic installation of earlier (more stable) Java versions from working properly. Even with the symbolic links fixed in the C:\ProgramData\Oracle\Java\javapath\ directory, I still was not completely "out of the woods" yet related to moving back to JDK 8 from the early release of JDK 9. I had some registry issues to address and this post summarizes that effort.

Error: Registry key 'Software\JavaSoft\Java Runtime Environment'\CurrentVersion'
has value '1.9', but '1.8' is required.
Error: could not find java.dll
Error: Could not find Java SE Runtime Environment.

The first warning ("Error: Registry key 'Software\JavaSoft\Java Runtime Environment'\CurrentVersion' has value '1.9', but '1.8' is required.") is addressed by changing the value of the registry described key (Software\JavaSoft\Java Runtime Environment\CurrentVersion) in exactly the recommended way (from 1.9 to 1.8 in my case).

The next screen snapshot shows my Windows 7 laptop's Registry Editor (started from DOS with regedit command) before I fixed the issue. The circled version ("1.9") is incorrect and right-clicking on the "CurrentVersion" key allowed me to select "Modify" and then to change the value field from 1.9" to "1.8" (see How to Modify the Windows Registry for more details on modifying the Windows Registry). I did the same for the "CurrentVersion" in "Software Development Kit" area as I did for the shown "Java Runtime Environment" area.

The screen snapshot of the Registry Editor also displays the issue related to the other two aspects of the warning message ("Error: could not find java.dll" and "Error: Could not find Java SE Runtime Environment."). As the screen snapshot demonstrates, there is no "1.8" area under "Java Runtime Environment" as there is for "1.6", "1.7", and "1.9". I created a "1.8" area under "Java Runtime Environment" and created keys in that area adapted from the "1.7" keys. The result is shown in the next screen snapshot.

You might notice that I removed the JDK 9 entries from the registry. I did this because I was only experimenting with JDK 9 before and was now ready to move back to the latest version of JDK 8 for more common uses. Also, I still have access to the downloaded archive file from which I installed JDK 9 and could use it again if so desired, but I think I'll be more likely to download the latest JDK 9 build (build 70 at time of this writing) and install it when I'm ready to experiment again with the latest JDK 9 has to offer.

Running "java -version" provides an easy way to determine that my Java runtime environment is working again.

There are no more registry errors when running Java! I can also tell that the fix has been successfully applied because starting up JEdit no longer leads to the message I was seen earlier which is reproduced here:

Bad or missing JRE/JDK registry entries can also affect Java IDEs and other Java-based applications, so it's good to have that all cleaned up.

Perhaps the easiest approach (in terms of needing to know very little about the details of the Windows registry) for cleaning up Java registry issues on a Windows machine is to follow the advice to remove all versions of Java from the system and re-install. However, that may seem a bit drastic and other approaches are discussed in the StackOverlow thread Error when checking Java version: could not find java.dll: reinstallation, checking for conflicting environment variables in both SYSTEM and USER environment variables, direct registry manipulation.

Oracle Java on Windows: C:\ProgramData\Oracle\Java\javapath

I recently downloaded an early access release of JDK 9 (build 68) for my Windows 7-based laptop. Because this is an early release, I was not surprised when the automatic installation introduced some less than ideal issues with the main Java Runtime Environment (JRE) installation on my laptop. After playing with the JDK 9 features that I wanted to try out, I downloaded the latest Oracle JDK 8 (Update 45) and used the automatic installer to install that. While still in that session, everything worked well.

When I powered up the laptop and logged in the next morning, my Java runtime environment was not healthy. The problem traced to specification of C:\ProgramData\Oracle\Java\javapath\java.exe as the first entry in my Path environment variable. When I changed directories to see the contents of the C:\ProgramData\Oracle\Java\javapath directory, I saw the following:

This screen snapshot indicates that the java.exe, javaw.exe, and javaws.exe entries in the C:\ProgramData\Oracle\Java\javapath\ directory are actually symbolic links (<SYMLINK>) to similarly named executables in the JRE 9 installation.

The next screen snapshot shows the effect of this on my Java runtime environment:

The message is very clear on what the issue is: "The system cannot find the file C:\ProgramData\Oracle\Java\javapath\java.exe." The reason that the system is looking for that is because the C:\ProgramData\Oracle\Java\javapath\ directory is the first entry in the Path and the symbolic links in that directory point to a JRE 9 directory that doesn't exist (I only have the JDK 9 directory):

StackOverflow user shpeley provides a nice overview of this situation and how he/she solved it. As I did, shpeley found that the automatic installer did not update these symbolic links when moving back versions (in shpeley's case, from JDK 8 to JDK 7). Borrowing from shpeley's solution (convenient because the syntax for making symbolic links in DOS is provided), I ran the following commands in the C:\ProgramData\Oracle\Java\javapath\ directory:

mklink java.exe "C:\Program Files\Java\jdk1.8.0_45\bin\java.exe"
mklink javaw.exe "C:\Program Files\Java\jdk1.8.0_45\bin\javaw.exe"
mklink javaws.exe "C:\Program Files\Java\jdk1.8.0_45\bin\javaws.exe"

The Oracle JDK/JRE installation on Windows normally goes very smoothly and, at most, I typically only need to change my %JAVA_HOME% environment variable to point to the new directory (when upgrading the JDK). However, when things occassionally don't go as smoothly, it's helpful to be aware of the directory C:\ProgramData\Oracle\Java\javapath\ and its symbolic links. In (fortunately rare) cases, it may even be necessary to change these symbolic links.


UPDATE: Ganesh's comment reminded me that it may be necessary to run Command Prompt (or Powershell) as Administrator to perform the operations discussed in this post. Two screen snapshots that follow demonstrate doing this in Windows 10. The first image shows right-clicking on "Command Prompt" and selecting "Run as administrator" and the second image shows what a Command Prompt window opened in that fashion looks like (in this case, it says "Administrator: Command Prompt" in the window's title bar rather than the normal "Command Prompt".