001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/datatypes/QualifiedName.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.datatypes;
037    
038    import java.io.Serializable;
039    import java.net.URI;
040    import java.net.URISyntaxException;
041    import java.util.Collections;
042    import java.util.HashMap;
043    import java.util.Map;
044    
045    import javax.xml.namespace.QName;
046    
047    import org.deegree.framework.log.ILogger;
048    import org.deegree.framework.log.LoggerFactory;
049    import org.deegree.framework.util.StringTools;
050    
051    /**
052     * This class represent a qualified name for something. A name is thought to be built from an optional prefix and/or a
053     * local name E.g.: <BR>- deegree - pre:deegree <BR>
054     * a name may be located within a namespace assigned to the names prefix (or as default namespace if the name has not
055     * prefix).
056     *
057     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
058     * @author last edited by: $Author: mschneider $
059     *
060     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
061     */
062    public class QualifiedName implements Serializable {
063    
064        private static final long serialVersionUID = 5551137348397905772L;
065    
066        private static final ILogger LOG = LoggerFactory.getLogger( QualifiedName.class );
067    
068        private String prefix = null;
069    
070        private String localName = null;
071    
072        private URI namespace = null;
073    
074        private String s = null;
075    
076        private static Map<URI, String> nsp = null;
077        static {
078            if ( nsp == null ) {
079                nsp = Collections.synchronizedMap( new HashMap<URI, String>() );
080            }
081        }
082    
083    
084        /**
085         * Creates a new <code>QualifiedName</code> instance from a <code>QName</code>
086         *
087         * @param name
088         */
089        public QualifiedName( QName name ) {
090            try {
091                this.prefix = name.getPrefix();
092                this.localName = name.getLocalPart();
093                this.namespace = new URI( name.getNamespaceURI() );
094                buildString();
095            } catch ( URISyntaxException e ) {
096                LOG.logError( "Invalid URI: " + e.getMessage(), e );
097            }
098        }
099    
100        /**
101         * @param name
102         *            local name/simple (without prefix)
103         */
104        public QualifiedName( String name ) {
105            if ( name.indexOf( '{' ) > -1 ) {
106                try {
107                    namespace = new URI( StringTools.extractStrings( name, "{", "}" )[0] );
108                } catch ( URISyntaxException e ) {
109                    //will never happen
110                }
111                int pos = name.lastIndexOf( ':' );
112                localName = name.substring( pos + 1 );
113            } else if ( name.indexOf( ':' ) > -1 ) {
114                String[] tmp = StringTools.toArray( name, ":", false );
115                if ( tmp.length == 2 ) {
116                    prefix = tmp[0];
117                    localName = tmp[1];
118                } else {
119                    localName = name;
120                }
121            } else {
122                this.localName = name;
123            }
124            buildString();
125        }
126    
127        /**
128         * @param name
129         *            complete name including a prefix
130         * @param namespace
131         *            namespace the name is located within
132         */
133        public QualifiedName( String name, URI namespace ) {
134            if ( name.indexOf( ':' ) > -1 ) {
135                String[] tmp = StringTools.toArray( name, ":", false );
136                this.prefix = tmp[0];
137                this.localName = tmp[1];
138            } else {
139                this.prefix = nsp.get( namespace );
140                if ( this.prefix == null ) {
141                    this.prefix = "app" + nsp.size();
142                    nsp.put( namespace, this.prefix );
143                }
144                this.localName = name;
145            }
146            this.namespace = namespace;
147            buildString();
148        }
149    
150        /**
151         * @param prefix
152         * @param localName
153         *            local/simple name (e.g. deegree)
154         * @param namespace
155         *            namespace the name is located within
156         */
157        public QualifiedName( String prefix, String localName, URI namespace ) {
158            this.prefix = prefix;
159            this.localName = localName;
160            this.namespace = namespace;
161            buildString();
162        }
163    
164        private void buildString() {
165            StringBuffer sb = new StringBuffer( 50 );
166            if ( prefix != null && prefix.length() != 0 ) {
167                sb.append( prefix ).append( ':' );
168            }
169            sb.append( localName );
170            s = sb.toString();
171        }
172    
173        /**
174         * returns a string representation of a QualifiedName. prefix and local name are separated by ':'
175         *
176         * @return string representation of a QualifiedName
177         * @deprecated use
178         * @see #getFormattedString() or
179         * @see #getPrefixedName() instead
180         */
181        @Deprecated
182        public String getAsString() {
183            return s;
184        }
185    
186        /**
187         * returns a string representation of a QualifiedName. prefix and local name are separated by ':'. If the Prefix is
188         * null, the sole localname will be returned.
189         *
190         * @return string representation of a QualifiedName
191         */
192        public String getPrefixedName() {
193            return s;
194        }
195    
196        /**
197         * @return a QualifiedName as a formatted string. If a QualifiedName has a namespace the returned format is:<br>
198         *         {namespace}:localName. <br>
199         *         Otherwise just a String representation of this qualified name will be returned. Which means, that if the
200         *         prefix is not null (allthough not bound to namespace) the result String will be: <br>
201         *         PRE_FIX:localName.<br>
202         *         If the Prefix is null, the sole localname will be returned.
203         */
204        public String getFormattedString() {
205            if ( namespace != null ) {
206                return StringTools.concat( 100, "{", namespace, "}:", localName );
207            }
208            return s;
209        }
210    
211        /**
212         * returns the names prefix
213         *
214         * @return the names prefix
215         */
216        public String getPrefix() {
217            return prefix;
218        }
219    
220        /**
221         * returns the local part of the name
222         *
223         * @return the local part of the name
224         */
225        public String getLocalName() {
226            return localName;
227        }
228    
229        /**
230         * returns the namespace the name is located within (may be null)
231         *
232         * @return the namespace the name is located within (may be null)
233         */
234        public URI getNamespace() {
235            return namespace;
236        }
237    
238        /**
239         * @param ns
240         *            the namespace to checkfor
241         * @return true if the given namespace equals this qualified name's namespace. If the given ns is null and the
242         *         namespace is null, this method will also return true.
243         */
244        public boolean isInNamespace( URI ns ) {
245            if ( ns == null ) {
246                if ( this.namespace == null ) {
247                    return true;
248                }
249                return false;
250            }
251            return ns.equals( this.namespace );
252        }
253    
254        @Override
255        public String toString() {
256            StringBuffer result = new StringBuffer( 150 );
257            result.append( this.s );
258            if ( this.prefix != null && this.prefix.length() > 0 ) {
259                result.append( " (" );
260                result.append( this.prefix );
261                result.append( "=" );
262                if ( this.namespace == null || this.namespace.toASCIIString().length() == 0 ) {
263                    result.append( "not bound to a namespace" );
264                } else {
265                    result.append( this.namespace.toASCIIString() );
266                }
267                result.append( ")" );
268            }
269            return result.toString();
270        }
271    
272        @Override
273        public int hashCode() {
274            return ( this.namespace + this.localName ).hashCode();
275        }
276    
277        @Override
278        public boolean equals( Object o ) {
279            // return false in the case that the object is null
280            // or isn't an instance of QualifiedName
281            if ( o == null || !( o instanceof QualifiedName ) ) {
282                return false;
283            }
284    
285            QualifiedName other = (QualifiedName) o;
286            if ( localName.equals( other.getLocalName() ) ) {
287                if ( ( namespace != null && namespace.equals( other.getNamespace() ) )
288                     || ( namespace == null && other.getNamespace() == null ) ) {
289                    return true;
290                }
291            }
292            return false;
293        }
294    }