    001    // $HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/owscommon/XMLFactory.java $
    002    /*----------------------------------------------------------------------------
    003     This file is part of deegree, http://deegree.org/
    004     Copyright (C) 2001-2009 by:
    005       Department of Geography, University of Bonn
    006     and
    007       lat/lon GmbH
    008
    009     This library is free software; you can redistribute it and/or modify it under
    010     the terms of the GNU Lesser General Public License as published by the Free
    011     Software Foundation; either version 2.1 of the License, or (at your option)
    012     any later version.
    013     This library is distributed in the hope that it will be useful, but WITHOUT
    014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
    016     details.
    017     You should have received a copy of the GNU Lesser General Public License
    018     along with this library; if not, write to the Free Software Foundation, Inc.,
    019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    020
    021     Contact information:
    022
    023     lat/lon GmbH
    024     Aennchenstr. 19, 53177 Bonn
    025     Germany
    026     http://lat-lon.de/
    027
    028     Department of Geography, University of Bonn
    029     Prof. Dr. Klaus Greve
    030     Postfach 1147, 53001 Bonn
    031     Germany
    032     http://www.geographie.uni-bonn.de/deegree/
    033
    034     e-mail: info@deegree.org
    035    ----------------------------------------------------------------------------*/
    036    package org.deegree.owscommon;
    037
    038    import static java.net.URLEncoder.encode;
    039    import static org.deegree.framework.util.CharsetUtils.getSystemCharset;
    040    import static org.deegree.framework.xml.XMLTools.appendElement;
    041    import static org.deegree.ogcbase.ExceptionCode.NOAPPLICABLECODE;
    042
    043    import java.io.UnsupportedEncodingException;
    044    import java.net.URI;
    045    import java.net.URL;
    046    import java.net.URLEncoder;
    047
    048    import org.deegree.datatypes.QualifiedName;
    049    import org.deegree.framework.util.CharsetUtils;
    050    import org.deegree.framework.xml.XMLFragment;
    051    import org.deegree.framework.xml.XMLTools;
    052    import org.deegree.model.metadata.iso19115.Address;
    053    import org.deegree.model.metadata.iso19115.ContactInfo;
    054    import org.deegree.model.metadata.iso19115.Keywords;
    055    import org.deegree.model.metadata.iso19115.Linkage;
    056    import org.deegree.model.metadata.iso19115.OnlineResource;
    057    import org.deegree.model.metadata.iso19115.Phone;
    058    import org.deegree.model.metadata.iso19115.TypeCode;
    059    import org.deegree.ogcbase.CommonNamespaces;
    060    import org.deegree.ogcwebservices.ExceptionDocument;
    061    import org.deegree.ogcwebservices.ExceptionReport;
    062    import org.deegree.ogcwebservices.OGCWebServiceException;
    063    import org.deegree.ogcwebservices.getcapabilities.DCPType;
    064    import org.deegree.ogcwebservices.getcapabilities.HTTP;
    065    import org.deegree.ogcwebservices.getcapabilities.Operation;
    066    import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata;
    067    import org.deegree.ogcwebservices.getcapabilities.ServiceIdentification;
    068    import org.deegree.ogcwebservices.getcapabilities.ServiceProvider;
    069    import org.w3c.dom.Element;
    070
    071    /**
    072     * Factory to create XML representations of components that are defined in the
    073     * <code>OWS Common Implementation Capabilities Specification 0.3</code>.
    074     *
    075     * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a>
    076     * @author last edited by: $Author: mschneider $
    077     *
    078     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
    079     */
    080    public class XMLFactory extends org.deegree.ogcbase.XMLFactory {
    081
    082        protected static final URI OWSNS = CommonNamespaces.OWSNS;
    083
    084        private static final String POGC = CommonNamespaces.OGC_PREFIX + ':';
    085
    086        protected static final URI DEEGREECSWNS = CommonNamespaces.DEEGREECSW;
    087
    088        /**
    089         * Exports an <tt>ExceptionReport</tt> to an XML Document as defined in the
    090         * <code>OGC common implementation specification 0.2.0</code>.
    091         *
    092         * @param exr
    093         * @return a new ServiceException document
    094         */
    095        public static XMLFragment export( ExceptionReport exr ) {
    096
    097            ExceptionDocument eDoc = new ExceptionDocument();
    098            eDoc.createEmptyDocument();
    099            Element node = eDoc.getRootElement();
    100
    101            for ( int i = 0; i < exr.getExceptions().length; i++ ) {
    102                appendException( node, exr.getExceptions()[i], false );
    103            }
    104
    105            return eDoc;
    106        }
    107
    108        /**
    109         * @param exr
    110         * @return a new ServiceException document
    111         */
    112        public static XMLFragment exportNS( ExceptionReport exr ) {
    113
    114            ExceptionDocument eDoc = new ExceptionDocument();
    115            eDoc.createEmptyDocumentNS();
    116            Element node = eDoc.getRootElement();
    117
    118            for ( int i = 0; i < exr.getExceptions().length; i++ ) {
    119                appendException( node, exr.getExceptions()[i], true );
    120            }
    121
    122            return eDoc;
    123
    124        }
    125
    126        /**
    127         * @param exr
    128         * @return a new ExceptionReport document according to OWS 1.0.0
    129         */
    130        public static XMLFragment exportExceptionReport( ExceptionReport exr ) {
    131            XMLFragment doc = new XMLFragment( new QualifiedName( "ows", "ExceptionReport", OWSNS ) );
    132            Element root = doc.getRootElement();
    133
    134            for ( int i = 0; i < exr.getExceptions().length; i++ ) {
    135                OGCWebServiceException exc = exr.getExceptions()[i];
    136                Element e = XMLTools.appendElement( root, OWSNS, "ows:Exception", exc.getMessage() );
    137                if ( exc.getCode() != null ) {
    138                    e.setAttribute( "exceptionCode", exc.getCode().value );
    139                }
    140
    141                String locator = exc.getLocator();
    142                try {
    143                    if ( locator != null ) {
    144                        locator = URLEncoder.encode( locator, CharsetUtils.getSystemCharset() );
    145                    } else {
    146                        locator = "unknown";
    147                    }
    148                } catch ( UnsupportedEncodingException _ ) {
    149                    // if catched why not do something -> setting locator to "unknown"
    150                    locator = "unknown";
    151                }
    152                e.setAttribute( "locator", locator );
    153            }
    154
    155            return doc;
    156
    157        }
    158
    159        /**
    160         * appends a xml representation of an <tt>OGCWebServiceException</tt> to the passed <tt>Element</tt>
    161         *
    162         * @param node
    163         * @param ex
    164         * @param namespace
    165         *            if true, the ogc prefix (bound to the ogc namespace) will be appended
    166         */
    167        protected static void appendException( Element node, OGCWebServiceException ex, boolean namespace ) {
    168
    169            if ( namespace ) {
    170                node = XMLTools.appendElement( node, OGCNS, POGC + "ServiceException", ex.getMessage() );
    171            } else {
    172                node = XMLTools.appendElement( node, null, "ServiceException", ex.getMessage() );
    173            }
    174
    175            if ( ex.getCode() != null ) {
    176                node.setAttribute( "code", ex.getCode().value );
    177            }
    178            String locator = ex.getLocator();
    179            try {
    180                if ( locator != null ) {
    181                    locator = URLEncoder.encode( locator, CharsetUtils.getSystemCharset() );
    182                } else {
    183                    locator = "unknown";
    184                }
    185            } catch ( UnsupportedEncodingException e ) {
    186                // if catched why not do something -> setting locator to "unknown"
    187                locator = "unknown";
    188            }
    189            node.setAttribute( "locator", locator );
    190        }
    191
    192        /**
    193         * Appends the DOM representation of the <code>ServiceIdentification</code>- section to the passed
    194         * <code>Element</code>.
    195         *
    196         * @param root
    197         * @param serviceIdentification
    198         */
    199        protected static void appendServiceIdentification( Element root, ServiceIdentification serviceIdentification ) {
    200
    201            // 'ServiceIdentification'-element
    202            Element serviceIdentificationNode = XMLTools.appendElement( root, OWSNS, "ows:ServiceIdentification" );
    203
    204            // 'ServiceType'-element
    205            XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:ServiceType",
    206                                    serviceIdentification.getServiceType().getCode() );
    207
    208            // 'ServiceTypeVersion'-elements
    209            String[] versions = serviceIdentification.getServiceTypeVersions();
    210            for ( int i = 0; i < versions.length; i++ ) {
    211                XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:ServiceTypeVersion", versions[i] );
    212            }
    213
    214            // 'Title'-element
    215            XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:Title", serviceIdentification.getTitle() );
    216
    217            // 'Abstract'-element
    218            if ( serviceIdentification.getAbstract() != null ) {
    219                XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:Abstract",
    220                                        serviceIdentification.getAbstract() );
    221            }
    222
    223            // 'Keywords'-element
    224            appendOWSKeywords( serviceIdentificationNode, serviceIdentification.getKeywords() );
    225
    226            // 'Fees'-element
    227            XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:Fees", serviceIdentification.getFees() );
    228
    229            // 'AccessConstraints'-element
    230            String[] constraints = serviceIdentification.getAccessConstraints();
    231            if ( constraints != null ) {
    232                for ( int i = 0; i < constraints.length; i++ ) {
    233                    XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:AccessConstraints", constraints[i] );
    234                }
    235            }
    236        }
    237
    238        /**
    239         * Appends a <code>ows:Keywords</code> -element for each <code>Keywords</code> object of the passed array to the
    240         * passed <code>Element</code>.
    241         *
    242         * @param xmlNode
    243         * @param keywords
    244         */
    245        protected static void appendOWSKeywords( Element xmlNode, Keywords[] keywords ) {
    246            if ( keywords != null ) {
    247                for ( int i = 0; i < keywords.length; i++ ) {
    248                    Element node = XMLTools.appendElement( xmlNode, OWSNS, "ows:Keywords" );
    249                    appendOWSKeywords( node, keywords[i] );
    250                }
    251            }
    252        }
    253
    254        /**
    255         * Appends a <code>ows:Keywords</code> -element to the passed <code>Element</code> and fills it with the available
    256         * keywords.
    257         *
    258         * @param xmlNode
    259         * @param keywords
    260         */
    261        protected static void appendOWSKeywords( Element xmlNode, Keywords keywords ) {
    262            if ( keywords != null ) {
    263                String[] kw = keywords.getKeywords();
    264                for ( int i = 0; i < kw.length; i++ ) {
    265                    XMLTools.appendElement( xmlNode, OWSNS, "ows:Keyword", kw[i] );
    266                }
    267                TypeCode typeCode = keywords.getTypeCode();
    268                if ( typeCode != null ) {
    269                    Element node = XMLTools.appendElement( xmlNode, OWSNS, "ows:Type", typeCode.getCode() );
    270                    if ( typeCode.getCodeSpace() != null ) {
    271                        node.setAttribute( "codeSpace", typeCode.getCodeSpace().toString() );
    272                    }
    273                }
    274            }
    275        }
    276
    277        /**
    278         * Appends the DOM representation of the <code>ServiceProvider</code>- section to the passed <code>Element</code>.
    279         *
    280         * @param root
    281         * @param serviceProvider
    282         */
    283        protected static void appendServiceProvider( Element root, ServiceProvider serviceProvider ) {
    284
    285            // 'ServiceProvider'-element
    286            Element serviceProviderNode = XMLTools.appendElement( root, OWSNS, "ows:ServiceProvider" );
    287
    288            // 'ProviderName'-element
    289            XMLTools.appendElement( serviceProviderNode, OWSNS, "ows:ProviderName", serviceProvider.getProviderName() );
    290
    291            // 'ProviderSite'-element
    292            if ( serviceProvider.getProviderSite() != null ) {
    293                Element providerSiteNode = XMLTools.appendElement( serviceProviderNode, OWSNS, "ows:ProviderSite" );
    294                appendSimpleLinkAttributes( providerSiteNode, serviceProvider.getProviderSite() );
    295            }
    296
    297            // 'ServiceContact'-element
    298            Element serviceContactNode = XMLTools.appendElement( serviceProviderNode, OWSNS, "ows:ServiceContact" );
    299
    300            // 'IndividualName'-element
    301            XMLTools.appendElement( serviceContactNode, OWSNS, "ows:IndividualName", serviceProvider.getIndividualName() );
    302
    303            // 'PositionName'-element
    304            if ( serviceProvider.getPositionName() != null ) {
    305                XMLTools.appendElement( serviceContactNode, OWSNS, "ows:PositionName", serviceProvider.getPositionName() );
    306            }
    307
    308            // 'ContactInfo'-element
    309            ContactInfo contactInfo = serviceProvider.getContactInfo();
    310            if ( contactInfo != null ) {
    311                Element contactInfoNode = XMLTools.appendElement( serviceContactNode, OWSNS, "ows:ContactInfo" );
    312                Phone phone = contactInfo.getPhone();
    313                if ( phone != null ) {
    314                    appendPhone( contactInfoNode, phone );
    315                }
    316                Address address = contactInfo.getAddress();
    317                if ( address != null ) {
    318                    appendAddress( contactInfoNode, address );
    319                }
    320                OnlineResource onlineResource = contactInfo.getOnLineResource();
    321                if ( onlineResource != null ) {
    322                    appendOnlineResource( contactInfoNode, "ows:OnlineResource", onlineResource, OWSNS );
    323                }
    324                String hoursOfService = contactInfo.getHoursOfService();
    325                if ( hoursOfService != null ) {
    326                    XMLTools.appendElement( contactInfoNode, OWSNS, "ows:HoursOfService", hoursOfService );
    327                }
    328                String contactInstructions = contactInfo.getContactInstructions();
    329                if ( contactInstructions != null ) {
    330                    XMLTools.appendElement( contactInfoNode, OWSNS, "ows:ContactInstructions", contactInstructions );
    331                }
    332            }
    333            TypeCode role = serviceProvider.getRole();
    334            if ( role != null ) {
    335                Element roleElement = XMLTools.appendElement( serviceContactNode, OWSNS, "ows:Role", role.getCode() );
    336                if ( role.getCodeSpace() != null ) {
    337                    roleElement.setAttribute( "codeSpace", role.getCodeSpace().toString() );
    338                }
    339            }
    340        }
    341
    342        /**
    343         * Appends the DOM representation of the <code>Phone</code> -section to the passed <code>Element</code>.
    344         *
    345         * @param root
    346         * @param phone
    347         */
    348        protected static void appendPhone( Element root, Phone phone ) {
    349
    350            // 'Phone'-element
    351            Element phoneNode = XMLTools.appendElement( root, OWSNS, "ows:Phone" );
    352
    353            // 'Voice'-elements
    354            String[] voiceNumbers = phone.getVoice();
    355            for ( int i = 0; i < voiceNumbers.length; i++ ) {
    356                XMLTools.appendElement( phoneNode, OWSNS, "ows:Voice", voiceNumbers[i] );
    357            }
    358
    359            // 'Facsimile'-elements
    360            String[] facsimileNumbers = phone.getFacsimile();
    361            for ( int i = 0; i < facsimileNumbers.length; i++ ) {
    362                XMLTools.appendElement( phoneNode, OWSNS, "ows:Facsimile", facsimileNumbers[i] );
    363            }
    364        }
    365
    366        /**
    367         * Appends the DOM representation of the <code>Address</code> -section to the passed <code>Element</code>.
    368         *
    369         * @param root
    370         * @param address
    371         */
    372        protected static void appendAddress( Element root, Address address ) {
    373
    374            // 'Address'-element
    375            Element addressNode = XMLTools.appendElement( root, OWSNS, "ows:Address" );
    376
    377            // 'DeliveryPoint'-elements
    378            String[] deliveryPoints = address.getDeliveryPoint();
    379            for ( int i = 0; i < deliveryPoints.length; i++ ) {
    380                XMLTools.appendElement( addressNode, OWSNS, "ows:DeliveryPoint", deliveryPoints[i] );
    381            }
    382
    383            // 'City'-element
    384            if ( address.getCity() != null ) {
    385                XMLTools.appendElement( addressNode, OWSNS, "ows:City", address.getCity() );
    386            }
    387
    388            // 'AdministrativeArea'-element
    389            if ( address.getAdministrativeArea() != null ) {
    390                XMLTools.appendElement( addressNode, OWSNS, "ows:AdministrativeArea", address.getAdministrativeArea() );
    391            }
    392
    393            // 'PostalCode'-element
    394            if ( address.getPostalCode() != null ) {
    395                XMLTools.appendElement( addressNode, OWSNS, "ows:PostalCode", address.getPostalCode() );
    396            }
    397
    398            // 'Country'-element
    399            if ( address.getCountry() != null ) {
    400                XMLTools.appendElement( addressNode, OWSNS, "ows:Country", address.getCountry() );
    401            }
    402
    403            // 'ElectronicMailAddress'-elements
    404            String[] electronicMailAddresses = address.getElectronicMailAddress();
    405            if ( address.getElectronicMailAddress() != null ) {
    406                for ( int i = 0; i < electronicMailAddresses.length; i++ ) {
    407                    XMLTools.appendElement( addressNode, OWSNS, "ows:ElectronicMailAddress", electronicMailAddresses[i] );
    408                }
    409            }
    410        }
    411
    412        /**
    413         * Appends the DOM representation of the <code>OperationsMetadata</code>- section to the passed <code>Element</code>
    414         * .
    415         *
    416         * @param root
    417         */
    418        protected static void appendOperationsMetadata( Element root, OperationsMetadata operationsMetadata ) {
    419
    420            // 'ows:OperationsMetadata'-element
    421            Element operationsMetadataNode = XMLTools.appendElement( root, OWSNS, "ows:OperationsMetadata" );
    422
    423            // append all Operations
    424            Operation[] operations = operationsMetadata.getOperations();
    425            for ( int i = 0; i < operations.length; i++ ) {
    426                Operation operation = operations[i];
    427
    428                // 'ows:Operation'-element
    429                Element operationElement = XMLTools.appendElement( operationsMetadataNode, OWSNS, "ows:Operation" );
    430                operationElement.setAttribute( "name", operation.getName() );
    431
    432                // 'ows:DCP'-elements
    433                DCPType[] dcps = operation.getDCPs();
    434                for ( int j = 0; j < dcps.length; j++ ) {
    435                    appendDCP( operationElement, dcps[j] );
    436                }
    437
    438                // 'ows:Parameter'-elements
    439                OWSDomainType[] parameters = operation.getParameters();
    440                for ( int j = 0; j < parameters.length; j++ ) {
    441                    appendParameter( operationElement, parameters[j], "ows:Parameter" );
    442                }
    443
    444                // 'ows:Metadata'-elements
    445                Object[] metadata = operation.getMetadata();
    446                if ( metadata != null ) {
    447                    for ( int j = 0; j < metadata.length; j++ ) {
    448                        appendMetadata( operationElement, metadata[j] );
    449                    }
    450                }
    451            }
    452
    453            // append general parameters
    454            OWSDomainType[] parameters = operationsMetadata.getParameter();
    455            for ( int i = 0; i < parameters.length; i++ ) {
    456                appendParameter( operationsMetadataNode, parameters[i], "ows:Parameter" );
    457            }
    458
    459            // append constraints
    460            OWSDomainType[] constraints = operationsMetadata.getConstraints();
    461            for ( int i = 0; i < constraints.length; i++ ) {
    462                appendParameter( operationsMetadataNode, constraints[i], "ows:Constraint" );
    463            }
    464        }
    465
    466        /**
    467         * Appends the DOM representation of a <code>DCPType</code> instance to the passed <code>Element</code>.
    468         *
    469         * @param root
    470         * @param dcp
    471         */
    472        protected static void appendDCP( Element root, DCPType dcp ) {
    473
    474            // 'ows:DCP'-element
    475            Element dcpNode = XMLTools.appendElement( root, OWSNS, "ows:DCP" );
    476
    477            // currently, the only supported DCP is HTTP!
    478            if ( dcp.getProtocol() instanceof HTTP ) {
    479                HTTP http = (HTTP) dcp.getProtocol();
    480
    481                // 'ows:HTTP'-element
    482                Element httpNode = XMLTools.appendElement( dcpNode, OWSNS, "ows:HTTP" );
    483
    484                // 'ows:Get'-elements
    485                URL[] getURLs = http.getGetOnlineResources();
    486                for ( int i = 0; i < getURLs.length; i++ ) {
    487                    appendOnlineResource( httpNode, "ows:Get", new OnlineResource( new Linkage( getURLs[i] ) ), OWSNS );
    488                }
    489
    490                // 'ows:Post'-elements
    491                URL[] postURLs = http.getPostOnlineResources();
    492                for ( int i = 0; i < postURLs.length; i++ ) {
    493                    appendOnlineResource( httpNode, "ows:Post", new OnlineResource( new Linkage( postURLs[i] ) ), OWSNS );
    494                }
    495            }
    496        }
    497
    498        /**
    499         * Appends the DOM representation of a <code>OWSDomainType</code> instance to the passed <code>Element</code>.
    500         *
    501         * @param root
    502         * @param parameter
    503         */
    504        protected static void appendParameter( Element root, OWSDomainType parameter, String elementName ) {
    505
    506            // 'ows:Parameter'-element
    507            Element parameterNode = XMLTools.appendElement( root, OWSNS, elementName );
    508            parameterNode.setAttribute( "name", parameter.getName() );
    509
    510            // 'ows:Value'-elements
    511            String[] values = parameter.getValues();
    512            for ( int i = 0; i < values.length; i++ ) {
    513                XMLTools.appendElement( parameterNode, OWSNS, "ows:Value", values[i] );
    514            }
    515        }
    516
    517        /**
    518         * Appends the DOM representation of a <code>Metadata</code> instance to the passed <code>Element</code>.
    519         *
    520         * @param root
    521         * @param metadata
    522         */
    523        protected static void appendMetadata( Element root, Object metadata ) {
    524
    525            // TODO
    526
    527        }
    528
    529        /**
    530         * @param exc
    531         * @return the exported new document
    532         */
    533        public static XMLFragment exportExceptionReportWFS( OGCWebServiceException exc ) {
    534            XMLFragment doc = new XMLFragment( new QualifiedName( "ows", "ExceptionReport", OWSNS ) );
    535            Element root = doc.getRootElement();
    536            root.setAttribute( "version", "1.1.0" );
    537
    538            Element e = appendElement( root, OWSNS, "ows:Exception" );
    539            if ( exc.getCode() != null ) {
    540                e.setAttribute( "exceptionCode", exc.getCode().value );
    541            } else {
    542                e.setAttribute( "exceptionCode", NOAPPLICABLECODE.value );
    543            }
    544
    545            String locator = exc.getLocator();
    546            try {
    547                if ( locator != null ) {
    548                    locator = encode( locator, getSystemCharset() );
    549                } else {
    550                    locator = "unknown";
    551                }
    552            } catch ( UnsupportedEncodingException _ ) {
    553                // if caught why not do something -> setting locator to "unknown"
    554                locator = "unknown";
    555            }
    556            e.setAttribute( "locator", locator );
    557
    558            appendElement( e, OWSNS, "ows:ExceptionText", exc.getMessage() );
    559
    560            return doc;
    561        }
    562
    563        /**
    564         * @param exc
    565         * @return the exported exception
    566         */
    567        public static XMLFragment exportExceptionReportWFS100( OGCWebServiceException exc ) {
    568            XMLFragment doc = new XMLFragment( new QualifiedName( "ogc", "ServiceExceptionReport", OGCNS ) );
    569            Element root = doc.getRootElement();
    570            root.setAttribute( "version", "1.2.0" );
    571
    572            Element e = appendElement( root, OGCNS, "ogc:ServiceException", exc.getMessage() );
    573            e.setAttribute( "code", exc.getCode() == null ? NOAPPLICABLECODE.value : exc.getCode().value );
    574
    575            String locator = exc.getLocator();
    576            try {
    577                if ( locator != null ) {
    578                    locator = encode( locator, getSystemCharset() );
    579                } else {
    580                    locator = "unknown";
    581                }
    582            } catch ( UnsupportedEncodingException _ ) {
    583                // if caught why not do something -> setting locator to "unknown"
    584                locator = "unknown";
    585            }
    586            e.setAttribute( "locator", locator );
    587
    588            return doc;
    589        }
    590
    591        /**
    592         * @param elem
    593         * @param name
    594         * @param value
    595         */
    596        public static void maybeSetAttribute( Element elem, String name, String value ) {
    597            if ( value != null ) {
    598                elem.setAttribute( name, value );
    599            }
    600        }
    601
    602    }