001    /*
002     * Copyright 2006 Stephen J. McConnell.
003     *
004     * Licensed  under the  Apache License,  Version 2.0  (the "License");
005     * you may not use  this file  except in  compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *   http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed  under the  License is distributed on an "AS IS" BASIS,
012     * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
013     * implied.
014     *
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    
019    package net.dpml.lang;
020    
021    import java.net.URI;
022    import java.util.Arrays;
023    
024    /**
025     * A Plugin class contains immutable data about a plugin based on a descriptor resolved
026     * from a 'plugin' artifact.
027     *
028     * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
029     * @version 1.1.0
030     */
031    public final class Classpath extends AbstractDirective
032    {
033        private static final URI[] EMPTY = new URI[0];
034        
035        private final URI[] m_system;
036        private final URI[] m_public;
037        private final URI[] m_protected;
038        private final URI[] m_private;
039        private final Classpath m_base;
040        
041       /**
042        * Creation of a empty classpath definition.
043        */
044        public Classpath()
045        {
046            this( EMPTY, EMPTY, EMPTY, EMPTY );
047        }
048        
049       /**
050        * Creation of a new classpath definition.
051        * @param base the base classpath from which this classpath is derived
052        * @param extension the extended classpath definition
053        */
054        public Classpath( final Classpath base, final Classpath extension )
055        {
056            if( null == extension )
057            {
058                throw new NullPointerException( "extension" );
059            }
060            m_base = base;
061            m_system = extension.m_system;
062            m_public = extension.m_public;
063            m_protected = extension.m_protected;
064            m_private = extension.m_private;
065        }
066        
067       /**
068        * Creation of a new classpath definition.
069        * @param systemUris an array of uris representing the system classpath extensions
070        * @param publicUris an array of uris representing the public classpath entries
071        * @param protectedUris an array of uris representing protected classpath entries
072        * @param privateUris an array of uris representing private classpath entries
073        */
074        public Classpath( 
075          URI[] systemUris, URI[] publicUris, URI[] protectedUris, URI[] privateUris )
076        {
077            this( null, systemUris, publicUris, protectedUris, privateUris );
078        }
079        
080       /**
081        * Creation of a new classpath definition.
082        * @param base super classpath (may be null)
083        * @param systemUris an array of uris representing the system classpath extensions
084        * @param publicUris an array of uris representing the public classpath entries
085        * @param protectedUris an array of uris representing protected classpath entries
086        * @param privateUris an array of uris representing private classpath entries
087        */
088        public Classpath( 
089          Classpath base, URI[] systemUris, URI[] publicUris, URI[] protectedUris, URI[] privateUris )
090        {
091            m_base = base;
092            if( null == systemUris )
093            {
094                m_system = EMPTY_URIS;
095            }
096            else
097            {
098                m_system = systemUris;
099            }
100            
101            if( null == publicUris )
102            {
103                m_public = EMPTY_URIS;
104            }
105            else
106            {
107                m_public = publicUris;
108            }
109            
110            if( null == protectedUris )
111            {
112                m_protected = EMPTY_URIS;
113            }
114            else
115            {
116                m_protected = protectedUris;
117            }
118            
119            if( null == privateUris )
120            {
121                m_private = EMPTY_URIS;
122            }
123            else
124            {
125                m_private = privateUris;
126            }
127        }
128        
129       /**
130        * Return the base classpath.
131        * @return the base classpath that this classpath extends (possibly null)
132        */
133        public Classpath getBaseClasspath()
134        {
135            return m_base;
136        }
137        
138       /**
139        * Return the classloader dependencies relative to a supplied classloader category.
140        *
141        * @param category the classloader category
142        * @return an array of uris defining the classloader classpath for the supplied category
143        */
144        public URI[] getDependencies( final Category category )
145        {
146            if( Category.SYSTEM.equals( category ) )
147            {
148                return m_system;
149            }
150            else if( Category.PUBLIC.equals( category ) )
151            {
152                return m_public;
153            }
154            else if( Category.PROTECTED.equals( category ) )
155            {
156                return m_protected;
157            }
158            else if( Category.PRIVATE.equals( category ) )
159            {
160                return m_private;
161            }
162            else
163            {
164                final String error = 
165                  "Category not recognized."
166                  + "\nCategory: " + category;
167                throw new IllegalArgumentException( error );
168            }
169        }
170        
171       /**
172        * Compare this object with another for equality.
173        * @param other the other object
174        * @return TRUE if equal else FALSE
175        */
176        public boolean equals( Object other )
177        {
178            if( other instanceof Classpath )
179            {
180                Classpath classpath = (Classpath) other;
181                //if( equals( m_base, classpath.m_base ) )
182                //{
183                //    return false;
184                //}
185                if( !Arrays.equals( m_system, classpath.getDependencies( Category.SYSTEM ) ) )
186                {
187                    return false;
188                }
189                if( !Arrays.equals( m_public, classpath.getDependencies( Category.PUBLIC ) ) )
190                {
191                    return false;
192                }
193                if( !Arrays.equals( m_protected, classpath.getDependencies( Category.PROTECTED ) ) )
194                {
195                    return false;
196                }
197                else
198                {
199                    return Arrays.equals( m_private, classpath.getDependencies( Category.PRIVATE ) );
200                }
201            }
202            else
203            {
204                return false;
205            }
206        }
207        
208       /**
209        * Return the hashcode for the plugin definition.
210        * @return the hash code
211        */
212        public int hashCode()
213        {
214            int hash = hashArray( m_system );
215            hash ^= hashArray( m_public );
216            hash ^= hashArray( m_protected );
217            hash ^= hashArray( m_private );
218            return hash;
219        }
220        
221       /**
222        * Return the classpath as a string.
223        * @return the string value
224        */
225        public String toString()
226        {
227            return "classpath: [" 
228              + m_system.length 
229              + ", " + m_public.length 
230              + ", " + m_protected.length 
231              + ", " + m_private.length
232              + "]";
233        }
234        
235        private static final URI[] EMPTY_URIS = new URI[0];
236        
237    }