In this section

Site navigation below

The Code Style site has evolved by gradual refinement and accumulation of features and content. This review is part of a fully backdated site log and archive that sheds light on when, why and how particular features were implemented.

This log is sometimes updated several times per week, sometimes with a long overdue backlog of items. Many log entries refer to the Code Style Java package that delivers the servlet services and utilities used to manage this site.

Subscribe to the news feed for this log: RSS news feed

Reverse chronology

30th June 2004

Completed the review of the Code Style Java project using PMD and applied a further range of enhancements and corrections. One general revision was to change all cases of NullPointerException thrown for null method arguments to IllegalArgumentException to distinguish from JVM exceptions.

Created a basic string message constructor for SourceException for cases where the exception is thrown directly, rather than wrapping another caught exception. In this case, the rootCause field refers to the instance itself. Switched to use this version in HttpRequest, StringBroker, TrustedHttpBroker and UntrustedHttpBroker. Also removed catch IllegalArgumentException blocks in constructors of TrustedHttpBroker and UntrustedHttpBroker to check null arguments directly.

Removed a debugging throws RuntimeException case in the ResultProxy class and commented out a catch SourceException statement until logging is implemented. Made the getLogEntry method of ResultLog public and simplified and renamed the isValidURL method.

29th June 2004

Started a review of the Code Style Java project using PMD with the pre-configured rule sets, making enhancements and corrections with each addition.

Simplified the BufferedReader readLine() loop in the ViewSource servlet to avoid assignment in the while statement.

while (true) {

    line = source.readLine();

    if (line == null) {

        break;
    }

    // Process output
}
      

Removed a null assignment in the ResultValue class and added checks for the empty string instead. Removed a null assignment in the getTransformer method of StylesheetCache and replaced with a local fresh variable.

Renamed a short to local variable in the AnchorPoints servlet to target.

Changed several Boolean instantiation statements in the SampleFactory class to use the static Boolean.valueOf() method.

Re-structured the try/catch IOException scheme in the getOutputStream method of ResultValue to avoid implication in program flow.

27th June 2004

Added a getURL method to the ServletUtilities class which does not filter ampersand characters in query strings, similar to the new makeURL method. This method is required to construct ResultKey objects that have a literal reference to the primary source.

Added a separate systemId field and accessor to the ResultKey class to distinguish fully-filtered from part-filtered URLs. The systemId value is used for obtaining input from Internet sources (via a SourceBroker), the fully-filtered xmlSystemId is used for published URLs and equivalence methods.

Adapted the ResultKeyBuilder class to the new setSystemId method of ResultKey by renaming its own mutator accordingly. Adapted all unit test classes to the new method names.

26th June 2004

Added unit tests for the recently implemented getLastModified and getExpires methods of the TrustedHttpBroker and UntrustedHttpBroker classes using the private Diagnostic servlet. These cases exposed a shortcoming in the ServletUtilities static makeURL method which creates URL objects from servlet parameter values. This method uses the getFirstParameter method, which passes parameter values through the filter method to strip out potentially malicious characters to prevent cross-site scripting attacks, see CERT Advisory CA-2000-02 Malicious HTML Tags. The SourceBrokerFactory uses this method indirectly to obtain URLs from query parameters. If the URL parameter contained a query with ampersands, these were escaped by the filter method to HTML entities, resulting in a bad request.

Created two new private, overloaded versions of the ServletUtilities methods getFirstParameter and filter to serve the public makeURL method, with special handling of ampersands to maintain original query parameters. Added extra unit tests to check various permutations of literal, URL-encoded and entity escaped queries do not affect the standard public versions of these methods. Also adapted the SourceBrokerFactory client to ensure appropriate use of these methods.

Changed the getFirstParameter and getServletInfor methods of ServletUtilities to throw a NullPointerException if any arguments are null, and set an initial StringBuffer size on the filter method. Also added a static constant for the HTTP URL prefix, http://.

Moved the abstract getExpires and close methods from SourceBroker up the class hierarchy to the Broker interface.

Added repetition exception tests for the getInputSource and getStreamSource methods of TrustedHttpBroker, and tests for getLastModified and getExpires methods of UntrustedHttpBroker.

Modified LimitedInputStream to retain, rather than reset, the totalBytes variable at the end of stream for later reporting of data transfer.

24th June 2004

Added a new field to the HttpRequest class to store any connection exception messages to report via a new accessor method. Added an Exception argument to the setErrorProperties method to assign the message and adapted the connect method to pass any IOException to it. Added unit tests for the ifModifiedSince argument for each input request method, and a getLastModified accessor check. Also added a check for no route to host handling.

Unit testing identified a misnamed HTTP Last-Modified header response in the private Diagnostic servlet.

23rd June 2004

Moved the ifModifiedSince field from HttpRequest up the class hierarchy to IORequest as a protected variable. The base getInputStream(long ifModifiedSince) method now assigns the date to the instance field for subclasses to handle as appropriate to their type.

Added a close method to TrustedHttpBroker which calls its private HttpRequest object's close method. Re-structured handling of the null response from HttpRequest instance's get input methods.

Modified the getInputStream method of FileRequest to check the superclass protected ifModifiedSince status before returning the stream reference, or null if not modified.

Moved the validation checks for HTTP content type and encoding from the UntrustedHttpRequest to HttpRequest, since they are equally valid at this level and cascaded down by the composition structure of UntrustedHttpRequest. Made the valid content types a string array in the migration to check a range of cases.

Added getContentLength, getContentType, getPath and getReferrer methods to UntrustedHttpRequest, which simply call the equivalent methods of the private HttpRequest. Added a mutator for the byte limit and a constructor with custom limit argument.

Extended HttpRequest tests to check valid content type and encoding for all input request methods. Added exception tests for repetition of getInputSource and getStreamSource methods in UntrustedHttpBroker.

Added a close method to StringBroker, which calls a private StringRequest instance. Adapted the StringRequest class getInputStream method to assign its ByteArrayInputStream to the protected superclass field inStream before returning a reference to it.

Removed all reset calls and instantiation checks from the ResultCacheSeriesTest, ResultProxySeriesTest and ResultProxyTest. Provided the cache is empty before each test, it does not matter whether it was previously instantiated or not.

22st June 2004

Added a protected InputStream field to the abstract superclass IORequest which serves as the source for all other input methods, and a protected boolean opened flag to check its status throughout the hierarchy. Also added a concrete close method to close the InputStream. Subclasses, including FileRequest, should assign their respective InputStream instances to this field before returning a reference so the various superclass get methods have access and can close the stream.

Added a set of get input methods to IORequest with long ifModifiedSince arguments to selectively download input source if it has changed. Added logic to cascade this check through all input request methods. Added an HTTP 200 status code constant, ifModifiedSince and responseCode variables to HttpRequest to carry through this scheme. If the modification check is set and the source has not changed, getInputStream returns null. Also added a getResponseCode method to check the response from the remote host in this case.

Added an abstract close method to the SourceBroker type to release resources tied-up with by the getInputSource and getStreamSource methods. Concrete implementations close their respective InputStream references, since this is the base type in all chained input (see above).

Amended the getInputStream repetition tests for the HttpRequest and FileRequest classes to expect a SourceException, since the input is already open. Also checked the repetition of calls to the getInputSource and getStreamSource methods of FileBroker throw the same exception.

Completed HttpRequest network tests for valid content type, content encoding and content length for all input requests methods.

Moved all getResult tests to the ResultProxySeriesTest class, leaving only constructor tests in ResultProxyTest. Added a check to the SourceBrokerFactoryTest that the service host field of the HttpServletRequest argument is not null.

21st June 2004

Added an abstract getExpires method to the SourceBroker class to carry through to TrustedHttpBroker and UntrustedHttpBroker, for use in the ResultProxy and ResultCache system. Implementations in FileBroker and StringBroker always return -1L, since this property is not relevant to these types.

Added a getExpires method to the UntrustedHttpRequest class that simply calls the equivalent method in the private HttpRequest field.

Changed the URLConnection field in HttpRequest to an HttpURLConnection type. Added a new connect method that ensures all accessible properties are stored whenever a connection is made, with a new connected flag to ensure only one connection is used. If the connection fails, a new setErrorProperties method assigns error case values to all properties. Updated all accessor methods and the getInputStream method to check the connected flag and call the new connect method as required.

Implemented the ResultProxy private setOutputProperties, setXslParameters and setXmlParserFeatures methods which assign parameters to the JAXP Transformer and XMLReader instances. Updated the makeResult method to get real modified and expiry dates from the SourceBroker instance. Also attempts to close the XML input source in the finally block.

Renamed the XSL output attribute mutator and accessor methods in ResultKey and ResultKeyBuilder to setXslOutputProperty and getXslOutputProperties respectively. Updated all clients and test classes as necessary.

Moved the testSaveLoad and testSaveLoadCheckSize methods from the ResultCacheTest class to ResultCacheSeriesTest, which maintains a ResultCache instance throughout.

Corrected the URI metadata in the Dublin Core RDF test case documents, which had an invalid Code Style domain. To update with the next re-deployment of the Web application.

20th June 2004

Completed testing and modifications to the new LimitedInputStream class and removed the redundant mark and markSupported methods, which are inherited from the superclass BufferedInputStream. Modified all unit tests to write temporary files from the input stream and check the byte lengths are identical or appropriate to the number of bytes skipped by the skip method.

Changed the UntrustedHttpRequest getInputStream method to return a LimitedInputStream from the getInputStream method, which is the root of all other input stream methods.

Changed the ResultProxySeriesTest class to use an instance field to hold all ResultProxy references to ensure the ResultCache it contains persists between tests.

Also made the abstract Cache class' addValue parameters final, and renamed the HttpRequest user agent field to "Code Style Web client/0.5"

17th June 2004

Moved the ResultCacheTest save method test to a new ResultCacheSeries test suite for tests that do not require a fresh ResultCache instance for each case.

16th June 2004

Created a new LimitedInputStream subclass of BufferedInputStream which limits the total throughput of un-trusted Internet sources, for use in the UntrustedHttpRequest class. This class overrides all read methods, skip and reset to maintain a running total of the bytes transferred. If the byte limit is exceeded these methods throw an IOException. Discovered the Sun Java 1.3 JDK version of the BufferedInputStream skip(long n) method always returns the requested skip value or -1L, not the actual number of skipped bytes, so the overridden skip method uses the protected pos field value to deduce the actual number of bytes skipped.

Added a parameter to the private Diagnostic servlet to return custom HTTP Content-Encoding responses for test purposes.

Re-instated the abstract addValue method of the superclass Cache, having debugged the concrete ResultCache implementation.

15th June 2004

Re-configured the ResultKeyBuilder class to use a private ResultKey field as the storage unit for configuring new instances. Adapted all mutator and accessor methods to the new structure. Also adapted the makeClone method to create a new instance with an independent ResultKey reference. The Object clone() method copies the reference to the original pre-configured ResultKey, which was invalidating the master prototype when properties were added to the cloned version. This version still fulfills the prototype pattern, so retains the method name makeClone().

Added a test to ResultKeyBuilderTest to ensure the pre-configured ResultKey field is copied rather than referenced with the makeClone method, as above.

Changed the getResult method of ResultCache to return null if the ResultKey is not matched, rather than throw an exception, since this is a normal operation of the class. Adapted the addValue method to replace any previous value with the same key, to prevent orphan cache files. Added a getResultCache method without arguments which assumes an instance has already been instantiated, throws a SingletonException if not.

Added a reset method to the ResultCache class to reset the instantiated flag and make the cache behave as if it has not been instantiated. This method is primarily for test purposes, to avoid making explicit calls to the finalize method, which is not good practise and was causing erratic test conditions. Adapted the ResultCacheTest class to the new reset method and added checks that the cache size is zero before conducting each test.

Added a ResultCache instantiation check to the constructor of ResultProxy with exception reporting, and changed to use the XSL system ID to instantiate the JAXP StreamSource used to compile Templates objects.

Adapted the ResultKey class to take a JAXP EntityResolver instance rather than a specification for the class, amended the hashCode and equals methods accordingly and added a getEntityResolver method. Changed all mutator methods to throw NullPointerException messages that identify the null argument.

Temporarily commented out the abstract addValue(CacheKey key, CacheValue value) in the ResultCache class to debug the equivalent ResultCache method with ResultKey and ResultValue arguments.

Moved the ResultProxyTest methods that require a persistent ResultCache instance to the ResultCacheProxySeriesTest class with checks that the cache is empty before each test.

Adapted ResultValueTest to the new CacheValueException and ObjectStateException scheme.

14th June 2004

Made the resources Hashtable in the ResourceResolver class transient, so it is not serialized when ResultKey objects are saved in the ResultCache class. Adjusted the hashCode and equals methods to disregard any the resources and added tests to the ResourceResolverTest class for serialization and deserialization.

13th June 2004

Retro-fitted the abstract CacheKey and CacheValue classes to extend the new SerialObject superclass, which implements the Serializable interface. Added JavaDoc comments to SerialObject.

Restructured all ResultCacheTest methods for more rigorous exception handling to ensure that the singleton ResultCache instance flag is reset before each test.

12th June 2004

Shortened the names of HttpContentRequest and UntrustedHttpContentRequest to just HttpRequest and UntrustedHttpRequest respectively. Adjusted all import statements, class references and variable names in client classes TrustedHttpBroker and UntrustedHttpBroker and their unit tests.

Corrected constructors with String arguments for the CacheValueException, ObjectStateException and SingletonException classes, which were not passing the message to the superclass constructor.

Corrected the logic for the fresh argument in the ResultCache getResult method and renamed the registry file based on its fully qualified class name, org.codestyle.xml.ResultCache.dat.

11th June 2004

Consolidated the DTD and entity set locator in the ResourceResolver class to a single field and added a new constructor to assign it directly. Separated out the initialisation of the resource Hashtable with a new configureResources method. Also added hashCode and equals methods so that the class can be added to the ResultKey object as an instance rather than a specification of locator and class name. Added new unit tests for the constructor and equivalence methods.

Created a new SerialObject superclass for cache objects that implements the Serializable interface to allow subclasses to implement other interfaces directly. Primarily required for the new ResourceResolver version, which must also implement the JAXP EntityResolver interface.

Renamed the JServDiagnostic servlet to just Diagnostic and added a set of parameters to set the HTTP response headers for unit testing purposes, including Modified, Expires, Content-Length, Content-Type, and Content-Encoding. Added an "untrusted" domain to the Ant local properties file, and the path of the Diagnostic servlet hosted there for testing the UntrustedHttpContentRequest class.

Commented out the JAXP EntityResolver class name from the Ant build and properties files, which is no longer required by the ResultKey unit test classes.

10th June 2004

Added an HTTP User-Agent header to the HttpContentRequest class and fields to store key response values, with accessors getContentLength, getContentEncoding, getContentType and getExpires. The new storeProperties method is called when a connection is made. Also set a new boolean opened flag to block repeated calls to getInputStream.

9th June 2004

Re-packaged the new XSL ResultCache hierarchy in the org.codestyle.xml package to escape some cyclic dependencies with the org.codestyle.broker and org.codestyle.cache packages. Updated all test classes accordingly.

Re-packaged early draft Cache, CacheKey and CacheValue into the org.codestyle.cache package. These classes had been set aside to concentrate on the concrete ResultCache, ResultKey and ResultValue classes respectively. Retro-fitted the generic cache classes as abstract superclasses of the concrete result cache classes.

The new abstract cache classes allowed the SourceBrokerFactory newBroker method to be modified to take a CacheKey argument, which de-couples it from the ResultKey implementation in the org.codesyle.xml package. Added more generic getSystemId and getServiceId methods to the abstract CacheKey class for use in the newBroker method, for more general purpose handling.

Added an org.xml.sax.driver system property to the Ant build configuration to test the ResultProxy class.

<sysproperty
  key="org.xml.sax.driver"
  value="org.apache.xerces.parsers.SAXParser"/>
      

8th June 2004

Updated the constructor for the ResultProxy class to use standardised systemId values as keys for compiled JAXP Templates objects via ResultKeyBuilder's validateSystemId method. The original file path reference scheme was causing a mis-match with the XSL templates.

Created a new checked CacheValueException class to report inappropriate CacheValue argument values and operations. Renamed the getFileModified method in ResultValue to getCacheModified and set a default date value of 0L for error cases to match the File lastModified method. Adapted the ResultValueTest class to the new exception scheme and method names.

Corrected handling of null HttpServletRequest arguments in the SourceBrokerFactory method newBroker. FileBroker instances were failing because of incorrect logic structure.

Re-factored the UntrustedHttpContentRequest class by composition with the standard HttpContentRequest.

Completed the review and clean-up of recent classes with Checkstyle. Made all methods and arguments final, reformatted long lines and conditional statements for:

Added an IOException to the FileSavePanel class if no file is specified. Implemented a standalone getContentType method in the ErrorTemplate class from the abstract signature in DocumentTemplate. Re-structured the logic of the setOmitXmlDeclaration method of ParseHandler to remove an inline conditional. Cleaned up JavaDoc notes about the ResultCache implementation in the ParseServlet class.

7th June 2004

Found a number of classes in the recent ResultCache class hierarchy where exception checking has been inconsistent because un-checked runtime exceptions had been used to flag bad arguments. Created a new ObjectStateException as a checked alternative to the runtime exception IllegalStateException. Also made SingletonException a subclass of Exception rather than RuntimeException. Initially applied the ObjectStateException to unmatched ResultKeys and stale ResultValues.

Adapted the unit test classes ResultKeyBuilderTest, ResultProxyTest, SourceBrokerFactory and RequestValveTest to the new checked exception scheme.

Made the getContentType method in the DocumentTemplate class abstract to force implementation in subclasses. Added getCreatedDate and hashCode methods to the Client class that represents an Internet client.

Conducted a review and clean-up of the Code Style Java project using Checkstyle. Applied enhancements and corrections to a broad range of recently created or adapted classes, including final modifiers on the majority of methods and arguments, removing "magic numbers" and re-formatting long lines in:

Also removed some redundant import statements in FileContentRequest, added JavaDoc comments to StringContentRequest.

6th June 2004

Implemented a getResult method for the ResultProxy class with a call to a new makeResult method if the result is not already cached. Added skeleton methods for configuring the JAXP Transformer and XMLReader objects before parsing.

Added an isStored method to the draft ResultValue class to ensure the XSL transformation result is stored before it is added to the cache. Also made all methods and arguments final, removed "magic numbers" for time variables and simplified logic for the boolean isFresh method.

5th June 2004

Upgraded xmlSystemId and xslSystemId handling in the ResultKeyBuilder class to ensure these references are stored as JAXP-compatible system ID values. A new validateSystemId method accepts a Web URL, file URL or file reference and passes back a well formed system identifier or throws a TransformerConfigurationException. File references are checked to see that they are readable.

Also renamed the setServiceUrl method to setXmlSystemId and added a private setXslSystemId method. Adapted the ResultKeyBuilderTest class to the new system ID scheme.

Prepared test cases for the newBroker(ResultKey key, HttpServletRequest request) method of SourceBrokerFactory for new FileBroker, TrustedHttpBroker and UntrustedHttpBroker instances. The new HttpServletRequest argument compares the local host against the requested source for HTTP types.

Found some erratic unit test failures with null ResultCache references, so added some finally statements to the exception test cases to clean up references.

4th June 2004

Added new logic to the SourceBrokerFactory class to issue FileBroker, TrustedHttpBroker and UntrustedHttpBroker instances with using ResultKey and HttpServletRequest arguments.

Previously on Code Style

These backdated pages record detailed changes to the Code Style Web site since July 2000, when development first got underway. Some pages may refer to documents or features that have since changed or are no longer part of the site, but the archive is checked to ensure there are no dead links.

Add this page to your chosen social bookmarking service

Style warning - please read

Home · CSS · Java · Javascript · HTML · Help · Log