001    //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/model/coverage/CodeList.java $
002    /*----------------------------------------------------------------------------
003     This file originated as a part of GeoAPI.
004    
005     GeoAPI is free software. GeoAPI may be used, modified and
006     redistributed by anyone for any purpose requring only maintaining the
007     copyright and license terms on the source code and derivative files.
008     See the OGC legal page for details.
009    
010     The copyright to the GeoAPI interfaces is held by the Open Geospatial
011     Consortium, see http://www.opengeospatial.org/ogc/legal
012    ----------------------------------------------------------------------------*/
013    package org.deegree.model.coverage;
014    
015    // J2SE direct dependencies
016    import java.io.InvalidObjectException;
017    import java.io.ObjectStreamException;
018    import java.io.Serializable;
019    import java.util.Collection;
020    
021    /**
022     * Base class for all code lists.
023     *
024     * @author <A HREF="http://www.opengis.org">OpenGIS&reg; consortium</A>
025     * @version 2.0
026     */
027    public abstract class CodeList implements Serializable {
028        /**
029         * Serial number for compatibility with different versions.
030         */
031        private static final long serialVersionUID = 5655809691319522885L;
032    
033        /**
034         * The code value. For J2SE 1.3 profile only.
035         */
036        private transient final int ordinal;
037    
038        /**
039         * The code name. For J2SE 1.3 profile only.
040         */
041        private final String name;
042    
043        /**
044         * Create a new code list instance.
045         *
046         * @param name
047         *            The code name.
048         * @param ordinal
049         *            The code value.
050         */
051        protected CodeList( final String name, final int ordinal ) {
052            this.name = name;
053            this.ordinal = ordinal;
054        }
055    
056        /**
057         * Create a new code list instance and add it to the given collection.
058         *
059         * @param name
060         *            The code name.
061         * @param values
062         *            The collection to add the enum to.
063         */
064        CodeList( final String name, final Collection<CodeList> values ) {
065            this.name = name;
066            synchronized ( values ) {
067                this.ordinal = values.size();
068                if ( !values.add( this ) ) {
069                    throw new IllegalArgumentException( String.valueOf( values ) );
070                }
071            }
072        }
073    
074        /**
075         * Returns the ordinal of this enumeration constant (its position in its enum declaration, where
076         * the initial constant is assigned an ordinal of zero).
077         *
078         * @return the ordinal of this enumeration constant.
079         */
080        public final int ordinal() {
081            return ordinal;
082        }
083    
084        /**
085         * Returns the name of this enum constant.
086         *
087         * @return the name of this enum constant.
088         */
089        public final String name() {
090            return name;
091        }
092    
093        /**
094         * Returns the list of enumerations of the same kind than this enum.
095         *
096         * @return the list of enumerations of the same kind than this enum.
097         */
098        public abstract CodeList[] family();
099    
100        /**
101         * Returns a string representation of this code list.
102         */
103        @Override
104        public String toString() {
105            String classname = getClass().getName();
106            final int i = classname.lastIndexOf( '.' );
107            if ( i >= 0 ) {
108                classname = classname.substring( i + 1 );
109            }
110            return classname + '[' + name + ']';
111        }
112    
113        /**
114         * Resolve the code list to an unique instance after deserialization. The instance is resolved
115         * using its {@linkplain #name() name} only (not its {@linkplain #ordinal() ordinal}).
116         *
117         * @return This code list as a unique instance.
118         * @throws ObjectStreamException
119         *             if the deserialization failed.
120         */
121        protected Object readResolve()
122                                throws ObjectStreamException {
123            final CodeList[] codes = family();
124            for ( int i = 0; i < codes.length; i++ ) {
125                if ( name.equals( codes[i].name ) ) {
126                    return codes[i];
127                }
128            }
129            throw new InvalidObjectException( toString() );
130        }
131    }