Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Nordstrom Java Utils is a small collection of general-purpose utility classes with wide applicability.

License

NotificationsYou must be signed in to change notification settings

sbabcoc/Java-Utils

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Maven Central

NORDSTROM JAVA UTILS

Nordstrom Java Utils is a small collection of general-purpose utility classes with wide applicability.

What You'll Find Here

StackTrace

TheStackTrace class extendsThrowable and it's intended to facilitate capture of the flow of execution that triggered system state changes that may lead to future operation errors. For example, an object that's no longer valid might get used subsequent to the event that caused it to become invalid, or a long-lived object may get discarded without corresponding resources being cleaned up.

For more details, check out theblog post that provided the implementation forStackTrace.

ExceptionUnwrapper

TheExceptionUnwrapper class provides methods for extracting the contents of "wrapped" exceptions.

UncheckedThrow

TheUncheckedThrow class uses type erasure to enable client code to throw checked exceptions as unchecked. This allows methods to throw checked exceptions without requiring clients to handle or declare them. It should be used judiciously, as this exempts client code from handling or declaring exceptions created by their own actions. The target use case for this facility is to throw exceptions that were serialized in responses from a remote system. Although the compiler won't require clients of methods using this technique to handle or declare the suppressed exception, the JavaDoc for such methods should include a@throws declaration for implementers who might want to handle or declare it voluntarily.

    ...Stringvalue;try {value =URLDecoder.decode(keyVal[1],"UTF-8");    }catch (UnsupportedEncodingExceptione) {throwUncheckedThrow.throwUnchecked(e);    }        ...

DatabaseUtils

DatabaseUtils provides facilities that enable you to define collections of database queries and stored procedures in an easy-to-execute format.

Query Collections

Query collections are defined as Java enumerations that implement theQueryAPI interface:

  • getQueryStr - Get the query string for this constant. This is the actual query that's sent to the database.
  • getArgNames - Get the names of the arguments for this query. This provides diagnostic information if the incorrect number of arguments is specified by the client.
  • getConnection - Get the connection string associated with this query. This eliminates the need for the client to provide this information.
  • getEnum - Get the enumeration to which this query belongs. This enablesexecuteQuery(Class, QueryAPI, Object[]) to retrieve the name of the query's enumerated constant for diagnostic messages.
  • ... see theJavaDoc for theQueryAPI interface for additional information.

Stored Procedure Collections

Store procedure collections are defined as Java enumerations that implement theSProcAPI interface:

  • getSignature - Get the signature for this stored procedure object. This defines the name of the stored procedure and the modes of its arguments. If the stored procedure acceptsvarargs, this will also be indicated (seeJavaDoc for details).
  • getArgTypes - Get the argument types for this stored procedure object.
  • getConnection - Get the connection string associated with this stored procedure. This eliminates the need for the client to provide this information.
  • getEnum - Get the enumeration to which this stored procedure belongs. This enablesexecuteStoredProcedure(Class, SProcAPI, Object[]) to retrieve the name of the stored procedured's enumerated constant for diagnostic messages.
  • ... see theJavaDoc for theSProcAPI interface for additional information.

Recommended Implementation Strategy

To maximize usability and configurability, we recommend the following implementation strategy:

  • Define your collection as an enumeration:

    • Query collections implement theQueryAPI interface.
    • Stored procedure collections implement theSProcAPI interface.
  • Define each constant:

    • (query) Specify a property name and a name for each argument (if any).
    • (sproc) Declare the signature and the type for each argument (if any).
  • To assist users of your queries, preface their names with a type indicator (GET orUPDATE).

  • Back query collections with configurations that implement theSettings API:

    • groupId: com.nordstrom.test-automation.tools
    • artifactId: settings
    • className: com.nordstrom.automation.settings.SettingsCore
  • To support execution on multiple endpoints, implementQueryAPI.getConnection() orSProcAPI.getConnection() with sub-configurations or other dynamic data sources (e.g. - web service).

Query Collection Example

publicclassOpctConfigextendsSettingsCore<OpctConfig.OpctValues> {privatestaticfinalStringSETTINGS_FILE ="OpctConfig.properties";privateOpctConfig()throwsConfigurationException,IOException {super(OpctValues.class);    }publicenumOpctValuesimplementsSettingsCore.SettingsAPI,QueryAPI {/** args: [  ] */GET_RULE_HEAD_DETAILS("opct.query.getRuleHeadDetails"),/** args: [ name, zone_id, priority, rule_type ] */GET_RULE_COUNT("opct.query.getRuleCount","name","zone_id","priority","rule_type"),/** args: [ role_id, user_id ] */UPDATE_USER_ROLE("opct.query.updateRsmUserRole","role_id","user_id"),/** MST connection string */MST_CONNECT("opct.connect.mst"),/** RMS connection string */RMS_CONNECT("opct.connect.rms");privateStringkey;privateString[]args;privateStringquery;privatestaticOpctConfigconfig;privatestaticStringmstConnect;privatestaticStringrmsConnect;privatestaticEnumSet<OpctValues>rmsQueries =EnumSet.of(UPDATE_USER_ROLE);static {try {config =newOpctConfig();            }catch (ConfigurationException |IOExceptione) {thrownewRuntimeException("Unable to instantiate OPCT configuration object",e);            }        }OpctValues(Stringkey,String...args) {this.key =key;this.args =args;        }@OverridepublicStringkey() {returnkey;        }@OverridepublicStringgetQueryStr() {if (query ==null) {query =config.getString(key);            }returnquery;        }@OverridepublicString[]getArgNames() {returnargs;        }@OverridepublicStringgetConnection() {if (rmsQueries.contains(this)) {returngetRmsConnect();            }else {returngetMstConnect();            }        }@OverridepublicEnum<OpctValues>getEnum() {returnthis;        }/**         * Get MST connection string.         *         * @return MST connection string         */publicstaticStringgetMstConnect() {if (mstConnect ==null) {mstConnect =config.getString(OpctValues.MST_CONNECT.key());            }returnmstConnect;        }/**         * Get RMS connection string.         *         * @return RMS connection string         */publicstaticStringgetRmsConnect() {if (rmsConnect ==null) {rmsConnect =config.getString(OpctValues.RMS_CONNECT.key());            }returnrmsConnect;        }    }@OverridepublicStringgetSettingsPath() {returnSETTINGS_FILE;    }/**     * Get OPCT configuration object.     *     * @return OPCT configuration object     */publicstaticOpctConfiggetConfig() {returnOpctValues.config;    }publicenumSProcValuesimplementsSProcAPI {/** args: [  ] */SHOW_SUPPLIERS("SHOW_SUPPLIERS()"),/** args: [ coffee_name, supplier_name ] */GET_SUPPLIER_OF_COFFEE("GET_SUPPLIER_OF_COFFEE(>, <)",Types.VARCHAR,Types.VARCHAR),/** args: [ coffee_name, max_percent, new_price ] */RAISE_PRICE("RAISE_PRICE(>, >, =)",Types.VARCHAR,Types.REAL,Types.NUMERIC),/** args: [ str, val... ] */IN_VARARGS("IN_VARARGS(<, >:)",Types.VARCHAR,Types.INTEGER),/** args: [ val, str... ] */OUT_VARARGS("OUT_VARARGS(>, <:)",Types.INTEGER,Types.VARCHAR);privateint[]argTypes;privateStringsignature;SProcValues(Stringsignature,int...argTypes) {this.signature =signature;this.argTypes =argTypes;        }@OverridepublicStringgetSignature() {returnsignature;        }@Overridepublicint[]getArgTypes () {returnargTypes;        }@OverridepublicStringgetConnection() {returnOpctValues.getRmsConnect();        }@OverridepublicEnum<SProcValues>getEnum() {returnthis;        }    }}

Registering JDBC Drivers

To provide maximum flexibility, JDBC interacts with database instances through a defined interface (java.sql.Driver). Implementations of this interface translate its methods into their vendor-specific protocol, in classes calleddrivers. For example,OracleDriver enables JDBC to interact with Oracle database products.

In JDBC connection URLs, the vendor and driver are specified as suffixes to thejdbc protocol. For the Oracle "thin" driver, this isjdbc:oracle:thin. This protocol/vendor/driver combination is handled byOracleDriver, and JDBC needs this class to be registered to handle this vendor-specific protocol.

To simplify the process of registering vendor-specific JDBC drivers,DatabaseUtils loads these for you through the JavaServiceLoader facility. Declare the driver(s) you need in aServiceLoader provider configuration file atMETA-INF/services/java.sql.Driver:

oracle.jdbc.OracleDriver

This sample provider configuration file will causeDatabaseUtils to load the JDBC driver class for Oracle database products. The JAR that declares this class needs to be on the class path for this to work. For Maven projects, you just need to add the correct dependency:

[pom.xml]<project ...>  [...]    <dependencies>    [...]    <dependency>      <groupId>com.oracle.jdbc</groupId>      <artifactId>ojdbc6</artifactId>      <version>11.2.0.4.0</version>    </dependency>  </dependencies>    [...]</project>

OSInfo

TheOSInfo class provides utility methods and abstractions for host operating system features.

VolumeInfo

TheVolumeInfo class provides methods that parse the output of the 'mount' utility into a mapped collection of volume property records.

PathUtils

ThePathUtils class provides a method to acquire the next file path in sequence for the specified base name and extension in the indicated target folder. If the target folder already contains at least one file that matches the specified base name and extension, the algorithm used to select the next path will always return a path whose index is one more than the highest index that currently exists. (If a single file with no index is found, its implied index is 0.)

Example usage ofgetNextPath
    .../*     * This example gets the next path in sequence for base name `artifact`     * and extension `txt` in the TestNG output directory.     *     * For purposes of this example, the output directory already contains     * the following files: `artifact.txt`, `artifact-3.txt`     */PathcollectionPath =Paths.get(testContext.getOutputDirectory());// => C:\git\my-project\test-output\Default suitePathartifactPath;try {artifactPath =PathUtils.getNextPath(collectionPath,"artifact","txt");// => C:\git\my-project\test-output\Default suite\artifact-4.txt    }catch (IOExceptione) {provider.getLogger().info("Unable to get output path; no artifact was captured",e);return;    }        ...

Params Interface

TheParams interface defines concise methods for the creation of named parameters and parameter maps. This facility can make your code much easier to read and maintain. The following example, which is extracted from theParams unit test class, demonstrates a few basic features.

Params Example

package com.nordstrom.example;import static com.nordstrom.common.params.Params.param;import static org.testng.Assert.assertEquals;import static org.testng.Assert.assertFalse;import static org.testng.Assert.assertTrue;import java.util.Optional;import org.testng.annotations.Test;import com.nordstrom.common.params.Params;public class ParamTest implements Params {        @Test    public void testDefault() {        assertFalse(Params.super.getParameters().isPresent());    }        @Test    public void testParam() {        Param param = param("boolean", true);        assertEquals(param.getKey(), "boolean");        verifyBoolean(param.getVal());    }        @Test    public void testParams() {        Optional<Map<String, Object>> optParameters = getParameters();        assertTrue(optParameters.isPresent());        Map<String, Object> parameters = optParameters.get();        assertFalse(parameters.isEmpty());                assertTrue(parameters.containsKey("boolean"));        verifyBoolean(parameters.get("boolean"));    }        private void verifyBoolean(Object value) {        assertTrue(value instanceof Boolean);        assertTrue((Boolean) value);    }        @Override    public Optional<Map<String, Object>> getParameters() {        return Params.mapOf(param("boolean", true), param("int", 1), param("String", "one"),                        param("Map", Params.mapOf(param("key", "value"))));    }}

This code uses a static import to eliminate redundant references to theParams interface. It also shows the unrestricted data types of parameter values. The use ofOptional objects enables you to provide an indication that no value was returned without the risks associated withnull.

JarUtils

TheJarUtils class provides methods related to Java JAR files.

  • getClasspath assembles a classpath string from the specified array of dependencies.
  • findJarPathFor finds the path to the JAR file from which the named class was loaded.
  • getJarPremainClass gets the 'Premain-Class' attribute from the indicated JAR file.

The methods of this class provide critical services for theLocal Grid feature ofSelenium Foundation, handling the task of locating the JAR files that declare the classes required by the Java-based servers it launches.

Assembling a Classpath String

ThegetClasspath method assembles a classpath string from the specified array of dependency contexts. This is useful for launching a Java sub-process, as it greatly simplifies the task of collecting the paths of JAR files that declare the classes required by your process. If any of the specified dependency contexts names thepremain class of a Java agent, the string returned by this method will contain two records delimited by anewline character:

  • 0 - assembled classpath string
  • 1 - tab-delimited list of Java agent paths

Finding a JAR File Path

ThefindJarPathFor method will find the absolute path to the JAR file from which the named class was loaded, provided the class has been loaded from a JAR file on the local file system.

Extracting thePremain-Class Attribute

ThegetJarPremainClass method will extract thePremain-Class attribute from the manifest of the indicated JAR file. The value of this attribute specifies the name of aJava agent class declared by the JAR.

UriUtils

As of Java 20, all of the constructors of theURL class have been deprecated. The recommended replacement is thetoURL() method of theURI class, but all of the constructors ofthis class throwURISyntaxtException. While this isn't a huge ordeal, having to handle this exception in contexts where the constructor arguments have already been validated can degrade code readability with no benefit to code safety. TheUriUtils class provides two convenience methods that employ the same strategy used by thecreate() method of theURI class - wrapping theURISyntaxException in anIllegalArgumentException:

  • makeBasicURI assembles a basic URI from the specified components - scheme, host, port, and path.
  • uriForPath assembles a URI for the specified path under the provided context.

Note that thetoURL() method of theURI class throws theMalformedURLException, but this exception is a subclass ofIOException, which affected code is almost certain to be handling already.

Written withStackEdit.


[8]ページ先頭

©2009-2025 Movatter.jp