<< Previous | Home | Next >>

Add CA Certificate To Java Keystore

It seems Oracle has changed parameters for the Java keytool command...

keytool -importcert -file ca-20130221.cer -alias wlvds -keystore cacerts -keypass changeit

List certificates in a keystore...

.\bin\keytool.exe -list -cacerts
Tags : ,
Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

Export this post as PDF document  Export this post to PDF document

JAXP Document Validation

Here's a nice class to validate XML Documents in Java:

package co.wlv.xml.validation;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.XMLConstants;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class XsdValidator {
    private static Logger logger = LoggerFactory.getLogger(Spike.class);

    private URL schemaUrl;
    private Schema schema;
    private LSResourceResolver resourceResolver;

    public XsdValidator(URL schemaUrl) throws SAXException {
        setSchemaUrl(schemaUrl);
        init();
    }

    public XsdValidator(URL schemaUrl, LSResourceResolver resourceResolver) throws SAXException {
        setSchemaUrl(schemaUrl);
        setResourceResolver(resourceResolver);
        init();
    }

    public List<SAXParseException> validateDocumentWithXsd(Document doc) {
        XsdErrorHandler xsdErrorHandler = new XsdErrorHandler();
        Validator validator = getSchema().newValidator();
        validator.setErrorHandler(xsdErrorHandler);

        DOMSource source = new DOMSource(doc);
        try {
            validator.validate(source);
        }
        catch (SAXException e) {
            logger.error("ERROR: validateDocumentWithXsd", e);
        }
        catch (IOException e) {
            logger.error("ERROR: validateDocumentWithXsd", e);
        }
        return xsdErrorHandler.getSaxParseExceptions();
    }

    public URL getSchemaUrl() {
        return schemaUrl;
    }

    public void setSchemaUrl(URL schemaUrl) {
        this.schemaUrl = schemaUrl;
    }

    public LSResourceResolver getResourceResolver() {
        return resourceResolver;
    }

    public void setResourceResolver(LSResourceResolver resourceResolver) {
        this.resourceResolver = resourceResolver;
    }

    private void init() throws SAXException {
        SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        if (resourceResolver != null)
            sf.setResourceResolver(resourceResolver);
        setSchema(sf.newSchema(getSchemaUrl()));
    }

    private Schema getSchema() {
        return schema;
    }

    private void setSchema(Schema schema) {
        this.schema = schema;
    }

    private class XsdErrorHandler implements ErrorHandler {
        private List<SAXParseException> saxParseExceptions = new ArrayList<SAXParseException>();

        @Override
        public void warning(SAXParseException e) throws SAXException {
            if (logger.isDebugEnabled())
                logger.debug(String.format("WARNING: %s", e.getMessage()));
            saxParseExceptions.add(e);
        }

        @Override
        public void fatalError(SAXParseException e) throws SAXException {
            if (logger.isDebugEnabled())
                logger.debug(String.format("FATAL: %s", e.getMessage()));
            saxParseExceptions.add(e);
        }

        @Override
        public void error(SAXParseException e) throws SAXException {
            if (logger.isDebugEnabled())
                logger.debug(String.format("ERROR: %s", e.getMessage()));
            saxParseExceptions.add(e);
        }

        public List<SAXParseException> getSaxParseExceptions() {
            return saxParseExceptions;
        }
    }
}

And a test case...

package co.wlv.spike.SpikeSchematron;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.URL;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.apache.log4j.xml.DOMConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class Spike {
    private static Logger logger = LoggerFactory.getLogger(Spike.class);
    private static File APIP_BASE = new File("etc/APIPv1p0_FinalRelease_20121017/Core_Level/Package");
    private static File APIP_ITEM_XSD = new File(APIP_BASE, "apipv1p0_qtiitemv2p1_v1p0.xsd");

    private static File APIP_ITEM_XML = new File("etc/samples/Item/VF656330.qti.xml");

    /**
     * @param args
     * @throws TransformerException
     * @throws ParserConfigurationException
     * @throws IOException
     * @throws SAXException
     */
    public static void main(String[] args) throws TransformerException, ParserConfigurationException, SAXException, IOException {
        DOMConfigurator.configure("etc/log4j.xml");

        Spike spike = new Spike();
        spike.doit();

        logger.debug("DONE!");
    }

    private void doit() throws ParserConfigurationException, SAXException, IOException {
        URL schemaUrl = APIP_ITEM_XSD.toURI().toURL();

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(APIP_ITEM_XML);

        XsdValidator xsdValidator = new XsdValidator(schemaUrl, new ApipLSResourceResolver());

        for (int i = 0; i < 1000; i++) {
            List<SAXParseException> saxParseExceptions = xsdValidator.validateDocumentWithXsd(doc);
            logger.debug(i + ") COUNT: " + saxParseExceptions.size());
        }
    }

    private class ApipLSResourceResolver implements LSResourceResolver {
        private Set<String> resolvedResources = new HashSet<String>();
        private Pattern apipPattern = Pattern.compile("^http://www.imsglobal.org/profile/apip/apipv1p0/[^/]*$");

        @Override
        public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
            if (logger.isDebugEnabled()) {
                logger.debug("============================================= resolveResource =============================================");
                logger.debug(String.format("NS_URI: %s; ", namespaceURI));
                logger.debug(String.format("PUB_ID: %s; ", publicId));
                logger.debug(String.format("SYS_ID: %s;", systemId));
                logger.debug(String.format("BASE_URI: %s", baseURI));
            }
            LSInput lsInput = null;
            if (systemId != null && !resolvedResources.contains(systemId)) {
                try {
                    String name = null;
                    if (systemId.equals("http://www.imsglobal.org/xsd/w3/2001/xml.xsd"))
                        name = "etc/xsd/xml.xsd";
                    else if (systemId.equals("http://www.imsglobal.org/xsd/w3/2001/XInclude.xsd"))
                        name = "etc/xsd/XInclude.xsd";
                    else if (systemId.equals("http://www.w3.org/Math/XMLSchema/mathml2/mathml2.xsd"))
                        name = "etc/xsd/mathml2/mathml2.xsd";
                    else if (apipPattern.matcher(systemId).matches())
                        name = String.format("%s/%s", APIP_BASE, systemId.replaceAll("^.*/", ""));

                    if (name != null) {
                        File file = new File(name);
                        if (logger.isDebugEnabled())
                            logger.debug("FILE: {}; EXISTS: {}; URI: {}", file, file.exists(), file.toURI());
                        if (file.exists()) {
                            lsInput = new LSInputImpl(new FileInputStream(file));
                            lsInput.setSystemId(file.toURI().toString());
                        }
                    }
                    resolvedResources.add(systemId);
                }
                catch (FileNotFoundException e) {
                    logger.error("Error resolving resource.", e);
                }
            }
            return lsInput;
        }
    }

    private class LSInputImpl implements LSInput {

        private String baseUri, encoding, publicId, systemId;
        private InputStream byteStream;

        public LSInputImpl(InputStream byteStream) {
            this.byteStream = byteStream;
        }

        @Override
        public String getBaseURI() {
            return baseUri;
        }

        @Override
        public InputStream getByteStream() {
            return byteStream;
        }

        @Override
        public boolean getCertifiedText() {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public Reader getCharacterStream() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public String getEncoding() {
            return encoding;
        }

        @Override
        public String getPublicId() {
            return publicId;
        }

        @Override
        public String getStringData() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public String getSystemId() {
            return systemId;
        }

        @Override
        public void setBaseURI(String baseURI) {
            baseUri = baseURI;
        }

        @Override
        public void setByteStream(InputStream byteStream) {
            this.byteStream = byteStream;
        }

        @Override
        public void setCertifiedText(boolean certifiedText) {
            // TODO Auto-generated method stub
        }

        @Override
        public void setCharacterStream(Reader characterStream) {
            // TODO Auto-generated method stub
        }

        @Override
        public void setEncoding(String encoding) {
            this.encoding = encoding;
        }

        @Override
        public void setPublicId(String publicId) {
            this.publicId = publicId;
        }

        @Override
        public void setStringData(String stringData) {
            // TODO Auto-generated method stub
        }

        @Override
        public void setSystemId(String systemId) {
            this.systemId = systemId;
        }
    }
}
Tags : , ,
Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

Export this post as PDF document  Export this post to PDF document

HTML5 WebSocket w/ Relative URL

I have been toying with the new WebSocket APIs in HTML5. This is a fantastic feature of the latest generation web standards that gives developers the ability to do two-way, streaming network communication directly in the web-browser from JavaScript. WebSockets have the potential to revolutionize performance of web applications, and so, revolutionize the ability of developers to offer rich, user-friendly and useful solutions to our clientele.

The current state of WebSocket development is that modern web-browser makers are all providing excellent WebSocket functionality. I tested with Microsoft IE 10, Mozilla Firefox 20, Google Chrome 25. All three browsers worked identically without any special cross-browser hacks. The server-side prognosis also seems good. Most of my dabbling has been with Tomcat's built in WebSocket support, but it seemed very solid. I was less pleased to learn that Apache HTTPD does not support proxing WebSocket requests via AJP or mod_proxy.

Tip of the day:

One of the quirks of the WebSocket API is that in order to create a new WebSocket object, you MUST pass a FQDN URL such as:

wss://my.domain/MyWebSocketService

However

window.location.href.replace(/^http(s?:\/\/.*)\/.*$/, 'ws$1/SpikeWebSocketServlet')
Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

Export this post as PDF document  Export this post to PDF document

Backing-up PostgreSQL Databases

I was excited to learn this morning that PostgreSQL has released a RC1 in the 9.2 line.  This is one more step on the way to the 9.2 stable release.  The news inspired me to update my development server, and once again I had to figure out how to use pg_dump.exe to backup my data.  So here's the one-liner that took me five minutes to work out.  Posting it here so I don't have to spend another five minutes!

bin\pg_dump.exe -f C:\_projects_\tmp\pg-20120901 -F d -v wlv.co
Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

Export this post as PDF document  Export this post to PDF document