001    //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_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: apoth $
059     *
060     * @version $Revision: 21574 $, $Date: 2009-12-21 16:37:50 +0100 (Mo, 21 Dez 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                this.prefix = nsp.get( namespace );
112                if ( this.prefix == null ) {
113                    this.prefix = "app" + nsp.size();
114                    nsp.put( namespace, this.prefix );
115                }
116                int pos = name.lastIndexOf( ':' );
117                localName = name.substring( pos + 1 );
118            } else if ( name.indexOf( ':' ) > -1 ) {
119                String[] tmp = StringTools.toArray( name, ":", false );
120                if ( tmp.length == 2 ) {
121                    prefix = tmp[0];
122                    localName = tmp[1];
123                } else {
124                    localName = name;
125                }
126            } else {
127                this.localName = name;
128            }
129            buildString();
130        }
131    
132        /**
133         * @param name
134         *            complete name including a prefix
135         * @param namespace
136         *            namespace the name is located within
137         */
138        public QualifiedName( String name, URI namespace ) {
139            if ( name.indexOf( ':' ) > -1 ) {
140                String[] tmp = StringTools.toArray( name, ":", false );
141                this.prefix = tmp[0];
142                this.localName = tmp[1];
143            } else {
144                this.prefix = nsp.get( namespace );
145                if ( this.prefix == null ) {
146                    this.prefix = "app" + nsp.size();
147                    nsp.put( namespace, this.prefix );
148                }
149                this.localName = name;
150            }
151            this.namespace = namespace;
152            buildString();
153        }
154    
155        /**
156         * @param prefix
157         * @param localName
158         *            local/simple name (e.g. deegree)
159         * @param namespace
160         *            namespace the name is located within
161         */
162        public QualifiedName( String prefix, String localName, URI namespace ) {
163            this.prefix = prefix;
164            this.localName = localName;
165            this.namespace = namespace;
166            buildString();
167        }
168    
169        private void buildString() {
170            StringBuffer sb = new StringBuffer( 50 );
171            if ( prefix != null && prefix.length() != 0 ) {
172                sb.append( prefix ).append( ':' );
173            }
174            sb.append( localName );
175            s = sb.toString();
176        }
177    
178        /**
179         * returns a string representation of a QualifiedName. prefix and local name are separated by ':'
180         *
181         * @return string representation of a QualifiedName
182         * @deprecated use
183         * @see #getFormattedString() or
184         * @see #getPrefixedName() instead
185         */
186        @Deprecated
187        public String getAsString() {
188            return s;
189        }
190    
191        /**
192         * returns a string representation of a QualifiedName. prefix and local name are separated by ':'. If the Prefix is
193         * null, the sole localname will be returned.
194         *
195         * @return string representation of a QualifiedName
196         */
197        public String getPrefixedName() {
198            return s;
199        }
200    
201        /**
202         * @return a QualifiedName as a formatted string. If a QualifiedName has a namespace the returned format is:<br>
203         *         {namespace}:localName. <br>
204         *         Otherwise just a String representation of this qualified name will be returned. Which means, that if the
205         *         prefix is not null (allthough not bound to namespace) the result String will be: <br>
206         *         PRE_FIX:localName.<br>
207         *         If the Prefix is null, the sole localname will be returned.
208         */
209        public String getFormattedString() {
210            if ( namespace != null ) {
211                return StringTools.concat( 100, "{", namespace, "}:", localName );
212            }
213            return s;
214        }
215    
216        /**
217         * returns the names prefix
218         *
219         * @return the names prefix
220         */
221        public String getPrefix() {
222            return prefix;
223        }
224    
225        /**
226         * returns the local part of the name
227         *
228         * @return the local part of the name
229         */
230        public String getLocalName() {
231            return localName;
232        }
233    
234        /**
235         * returns the namespace the name is located within (may be null)
236         *
237         * @return the namespace the name is located within (may be null)
238         */
239        public URI getNamespace() {
240            return namespace;
241        }
242    
243        /**
244         * @param ns
245         *            the namespace to checkfor
246         * @return true if the given namespace equals this qualified name's namespace. If the given ns is null and the
247         *         namespace is null, this method will also return true.
248         */
249        public boolean isInNamespace( URI ns ) {
250            if ( ns == null ) {
251                if ( this.namespace == null ) {
252                    return true;
253                }
254                return false;
255            }
256            return ns.equals( this.namespace );
257        }
258    
259        @Override
260        public String toString() {
261            StringBuffer result = new StringBuffer( 150 );
262            result.append( this.s );
263            if ( this.prefix != null && this.prefix.length() > 0 ) {
264                result.append( " (" );
265                result.append( this.prefix );
266                result.append( "=" );
267                if ( this.namespace == null || this.namespace.toASCIIString().length() == 0 ) {
268                    result.append( "not bound to a namespace" );
269                } else {
270                    result.append( this.namespace.toASCIIString() );
271                }
272                result.append( ")" );
273            }
274            return result.toString();
275        }
276    
277        @Override
278        public int hashCode() {
279            return ( this.namespace + this.localName ).hashCode();
280        }
281    
282        @Override
283        public boolean equals( Object o ) {
284            // return false in the case that the object is null
285            // or isn't an instance of QualifiedName
286            if ( o == null || !( o instanceof QualifiedName ) ) {
287                return false;
288            }
289    
290            QualifiedName other = (QualifiedName) o;
291            if ( localName.equals( other.getLocalName() ) ) {
292                if ( ( namespace != null && namespace.equals( other.getNamespace() ) )
293                     || ( namespace == null && other.getNamespace() == null ) ) {
294                    return true;
295                }
296            }
297            return false;
298        }
299    }