001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/metadata/iso19115/ISO19115Document.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003     This file is part of deegree.
004     Copyright (C) 2001-2007 by:
005     Department of Geography, University of Bonn
006     http://www.giub.uni-bonn.de/deegree/
007     lat/lon GmbH
008     http://www.lat-lon.de
009     This library is free software; you can redistribute it and/or
010     modify it under the terms of the GNU Lesser General Public
011     License as published by the Free Software Foundation; either
012     version 2.1 of the License, or (at your option) any later version.
013     This library is distributed in the hope that it will be useful,
014     but WITHOUT ANY WARRANTY; without even the implied warranty of
015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016     Lesser General Public License for more details.
017     You should have received a copy of the GNU Lesser General Public
018     License along with this library; if not, write to the Free Software
019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020     Contact:
021     Andreas Poth
022     lat/lon GmbH
023     Aennchenstraße 19
024     53177 Bonn
025     Germany
026     E-Mail: poth@lat-lon.de
027     Jens Fitzke
028     lat/lon GmbH
029     Aennchenstraße 19
030     53177 Bonn
031     Germany
032     E-Mail: jens.fitzke@uni-bonn.de
033     ---------------------------------------------------------------------------*/
034    package org.deegree.model.metadata.iso19115;
035    
036    import java.net.MalformedURLException;
037    import java.net.URI;
038    import java.net.URL;
039    import java.util.ArrayList;
040    import java.util.List;
041    
042    import org.deegree.datatypes.Code;
043    import org.deegree.framework.xml.XMLFragment;
044    import org.deegree.framework.xml.XMLParsingException;
045    import org.deegree.framework.xml.XMLTools;
046    import org.deegree.ogcbase.CommonNamespaces;
047    import org.w3c.dom.Element;
048    
049    /**
050     * Parser class that can parse various elements defined in the OWS subset of the ISO 19115 specification.
051     * 
052     * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a>
053     * @author last edited by: $Author: apoth $
054     * 
055     * @version 2.0, $Revision: 6845 $, $Date: 2007-05-07 11:28:14 +0200 (Mo, 07 Mai 2007) $
056     * 
057     * @since 2.0
058     */
059    
060    public class ISO19115Document extends XMLFragment {
061    
062        private static final long serialVersionUID = -5536802360612196021L;
063    
064        private static final String POWS = CommonNamespaces.OWS_PREFIX + ":";
065        
066        private static final String PXLINK = CommonNamespaces.XLINK_PREFIX + ":";
067        
068        /**
069         * @param root an element of type ows:ResponsiblePartySubsetType
070         * @return the data object
071         * @throws XMLParsingException
072         */
073        public CitedResponsibleParty parseCitedResponsibleParty( Element root ) throws XMLParsingException {
074            String individualName = XMLTools.getNodeAsString( root, POWS + "IndividualName", nsContext, null );
075            
076            String positionName = XMLTools.getNodeAsString( root, POWS + "PositionName", nsContext, null );
077            
078            Element roleElement = (Element) XMLTools.getNode( root, POWS + "Role", nsContext );
079            RoleCode role = null;
080            if( roleElement != null ) role = parseRoleCode( roleElement );
081            
082            Element contactElement = (Element) XMLTools.getNode( root, POWS + "ContactInfo", nsContext );
083            ContactInfo contactInfo = null;
084            if( contactElement != null ) contactInfo = parseContactInfo( contactElement );
085            
086            // why Lists/Arrays are necessary here is beyond my knowledge
087            List<String> name = new ArrayList<String>();
088            name.add( individualName );
089            List<String> pName = new ArrayList<String>();
090            pName.add( positionName );
091            List<RoleCode> roles = new ArrayList<RoleCode>();
092            roles.add( role );
093            List<ContactInfo> contactInfos = new ArrayList<ContactInfo>();
094            contactInfos.add( contactInfo );
095            
096            CitedResponsibleParty result = new CitedResponsibleParty( contactInfos, name, null, pName, roles );
097            return result;
098        }
099        
100        /**
101         * @param root the ContactInfo element
102         * @return the <code>ContactInfo</code> data object
103         * @throws XMLParsingException 
104         */
105        public ContactInfo parseContactInfo( Element root ) throws XMLParsingException {
106            Element phoneElement = (Element) XMLTools.getNode( root, POWS + "Phone", nsContext );
107            Phone phone = null;
108            if( phoneElement != null ) phone = parsePhone( phoneElement );
109            
110            Address address = null;
111            Element addressElement = (Element) XMLTools.getNode( root, POWS + "Address", nsContext );
112            if( addressElement != null ) address = parseAddress( addressElement );
113            
114            OnlineResource onlineResource = null;
115            Element onlineResourceElement = (Element) XMLTools.getNode( root, POWS + "OnlineResource", nsContext );
116            if( onlineResourceElement != null ) onlineResource = parseOnlineResource( onlineResourceElement );
117            
118            String hoursOfService = XMLTools.getNodeAsString( root, POWS + "HoursOfService", nsContext, null );
119            String contactInstructions = XMLTools.getNodeAsString( root, POWS + "ContactInstructions", nsContext, null );
120            
121            ContactInfo result = new ContactInfo( address, contactInstructions, hoursOfService, onlineResource, phone );
122            return result;
123        }
124        
125        /**
126         * @param root the Address element
127         * @return the <code>Address</code> data object
128         * @throws XMLParsingException
129         */
130        public Address parseAddress( Element root ) throws XMLParsingException {
131            String[] deliveryPoint = XMLTools.getNodesAsStrings( root, POWS + "DeliveryPoint", nsContext );
132            String city = XMLTools.getNodeAsString( root, POWS + "City", nsContext, null );
133            String administrativeArea = XMLTools.getNodeAsString( root, POWS + "AdministrativeArea", nsContext, null );
134            String postalCode = XMLTools.getNodeAsString( root, POWS + "PostalCode", nsContext, null );
135            String country = XMLTools.getNodeAsString( root, POWS + "Country", nsContext, null );
136            String[] emails = XMLTools.getNodesAsStrings( root, POWS + "ElectronicMailAddress", nsContext );
137            
138            Address result = new Address( administrativeArea, city, country, deliveryPoint, emails, postalCode );
139            return result;
140        }
141        
142        /**
143         * @param root the Phone element
144         * @return a <code>Phone</code> data object
145         * @throws XMLParsingException
146         */
147        public Phone parsePhone( Element root ) throws XMLParsingException {
148            String[] voice = XMLTools.getNodesAsStrings( root, POWS + "Voice", nsContext );
149            
150            String[] facsimile = XMLTools.getNodesAsStrings( root, POWS + "Facsimile", nsContext );
151            
152            Phone result = new Phone( facsimile, voice );
153            return result;
154        }
155        
156        /**
157         * @param root the element containing the xlink attributes
158         * @return the <code>OnlineResource</data> data object
159         * @throws XMLParsingException
160         */
161        public OnlineResource parseOnlineResource( Element root ) throws XMLParsingException {
162            // This is just a preview version, not sure how to handle all the xlink attributes
163            // correctly.
164            
165            URL href = null;
166            String url = null;
167    
168            try {
169                url = XMLTools.getNodeAsString( root, "@" + PXLINK + "href", nsContext, null );
170                if( url != null ) href = new URL( url );
171            } catch ( MalformedURLException e ) {
172                throw new XMLParsingException( "'"
173                                               + url + "' is not a valid URL." );
174            }
175    
176            Linkage linkage = new Linkage( href );
177            OnlineResource result = new OnlineResource( linkage );
178            return result;
179        }
180        
181        /**
182         * @param root the Code element
183         * @return a <code>Code</code> data object
184         */
185        public Code parseCode( Element root ) {
186            URI codeSpace = null;
187            try{
188                codeSpace = new URI( XMLTools.getAttrValue( root, null, "codeSpace", null ) );
189            } catch ( Exception e ) {
190                // ignore codeSpace
191            }
192            
193            String code = XMLTools.getStringValue( root );
194            
195            if( codeSpace != null ) return new Code( code, codeSpace );
196            return new Code( code );
197        }
198        
199        /**
200         * @param root the Type element
201         * @return the <code>TypeCode</code> data object
202         */
203        public TypeCode parseTypeCode( Element root ) {
204            Code code = parseCode( root );
205            // since the TypeCode class already existed, it is used. Deleting the TypeCode class and
206            // just using the Code class would be the better solution, though.
207            return new TypeCode( code.getCode(), code.getCodeSpace() );
208        }
209        
210        /**
211         * @param root the Role element
212         * @return the <code>RoleCode</code> data object
213         */
214        public RoleCode parseRoleCode( Element root ) {
215            Code code = parseCode( root );
216            // since the RoleCode class already existed, it is used. Deleting the RoleCode class and
217            // just using the Code class would be the better solution, though.
218            return new RoleCode( code.getCode() );
219        }
220        
221        /**
222         * @param root the AccessConstraints element
223         * @param fee
224         * @return the <code>Constraints</code> object containing the parsed data
225         * @throws XMLParsingException
226         */
227        public Constraints parseConstraint( Element root, String fee ) throws XMLParsingException {
228            // please note that the same fee is used for all constraints
229            
230            List<String> constr = new ArrayList<String>();
231            String str = XMLTools.getRequiredNodeAsString( root, ".", nsContext );
232            constr.add( str );
233            
234            Constraints result = new Constraints( fee, null, null, null, constr, null, null, null );
235            return result;
236        }
237        
238        /**
239         * @param root the Keywords element
240         * @return the <code>Keywords</code> object
241         * @throws XMLParsingException
242         */
243        public Keywords parseKeywords( Element root ) throws XMLParsingException {
244            String[] keywords = XMLTools.getRequiredNodesAsStrings( root, POWS + "Keyword", nsContext );
245            Element codeElem = (Element) XMLTools.getNode( root, POWS + "Type", nsContext );
246            TypeCode type = null;
247            if( codeElem != null ) type = parseTypeCode( codeElem );
248            
249            Keywords result = null;
250    
251            // the thesaurus name is ignored at the moment, as it is omitted by the OWS specification as well
252            if( type != null ) result = new Keywords( keywords );
253            else result = new Keywords( keywords, "", type );
254            
255            return result;
256        }
257        
258    }