Parsing XML in XPRESS Rules Within Sun’s Identity Manager

I’ve been doing a lot of work with Sun’s Identity Manager lately, and have some things that might be of interest to other’s so I’ll try to post them here as time permits.

I think the coolest thing I’ve done so far is to build a library for parsing XML within XPRESS. It’s actually fairly straightforward, but it took me long enough to get right that it seems like a good thing to share. I have 2 XPRESS rules:

transformXML
Takes 2 strings, xml and xsl, as input, and returns the transformed data.
validateXML
Takes 2 strings, xml and xsd, as input, and returns 1 true if the XML validates against the XSD, and returns false otherwise.

Both rules invoke Java to do the actual work, but for reasons I’ll explain later, validateXML is a bit more complex than transformXML. The XML transformation is simply a matter of figuring out the proper incantation to invoke:

<Rule name='transformXML'>
    <RuleArgument name='xml'/>
    <RuleArgument name='xsl'/>

    <block>
        <defvar name="StringWriter">
            <new class="java.io.StringWriter"/>
        </defvar>
        <invoke name="transform">
            <invoke name="newTransformer">
                <invoke name="newInstance" class="javax.xml.transform.TransformerFactory"/>
                <new class="javax.xml.transform.stream.StreamSource">
                    <new class="java.io.StringReader">
                        <ref>xsl</ref>
                    </new>
                </new>
            </invoke>
            <new class="javax.xml.transform.stream.StreamSource">
                <new class="java.io.StringReader">
                    <ref>xml</ref>
                </new>
            </new>
            <new class="javax.xml.transform.stream.StreamResult">
                <ref>StringWriter</ref>
            </new>
        </invoke>

        <invoke name="toString">
            <ref>StringWriter</ref>
        </invoke>
    </block>
</Rule>

That looks fairly complicated, but it is pretty much a straight translation from the Java to XPRESS invocations. Unfortunately, XML validation isn’t quite as straightforward. If there is a way to do it without exception handling, which is not available in XPRESS, I don’t know what that way is. So, the direct invocations similar to the code above will not work.

It would be possible to write a bit of simple Java code to wrap the exception handling in a nice set of return codes, deploy that code with the IDM deployment and then invoke that from XPRESS, but I was really hoping to avoid custom Java if possible. In this case, JavaScript comes to the rescue (man, I never thought I would say that):

<Rule name='validateXML'>
    <RuleArgument name='xsd'/>
    <RuleArgument name='xml'/>

    <cond>
        <and>
            <notnull>
                <ref>xsd</ref>
            </notnull>
            <notnull>
                <ref>xml</ref>
            </notnull>
        </and>
        <script>
            importPackage(Packages.javax.xml.validation);
            importPackage(Packages.java.io);
            importPackage(Packages.javax.xml.transform.stream);

            var xsd = env.get('xsd');
            var xml = env.get('xml');

            var schemaFactory = SchemaFactory.newInstance('http://www.w3.org/2001/XMLSchema');
            var schema = schemaFactory.newSchema(new StreamSource(new StringReader(xsd)));

            var validator = schema.newValidator();

            var result = 'true';

            try {
                validator.validate(new StreamSource(new StringReader(xml)));
            }
            catch(err) {
                result = 'false';
            }

            result;
        </script>
        <s>false</s>
    </cond>
</Rule>

I’ve attached a rule library containing both these rules that you should be able to import and use in your project.

Have Fun.

Configuration-xmlRuleLibrary.xml

linksysmon Is Dead, Long Live linksysmon

Well, it looks like there might still be some interest in linksysmon, so I’ve put a link to the final tar file here.

linksysmon-1.1.4.tar.gz

linksysmon Is Dead, Long Live openwrt

With the update of the new site, I’m dropping support for linksysmon all together. A cursory glance at the logs finds no downloads from anything but the search engines, and I’ve upgraded my router hardware to a Linksys WRT54GL, so I don’t even use it anymore. Instead, I use openwrt.