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.io.IOException;
022    import java.io.Writer;
023    import java.net.URL;
024    
025    import net.dpml.state.StateListener;
026    
027    import net.dpml.util.Logger;
028    import dpml.lang.Disposable;
029    
030    /**
031     * Simple resource deployment strategy.
032     * @author <a href="http://www.dpml.net">Digital Product Management Laboratory</a>
033     * @version 2.0.1
034     */
035    public class AntlibStrategy extends Strategy
036    {
037        private final String m_urn;
038        private final String m_path;
039        
040       /**
041        * Creation of resource datatype.
042        * @param classloader the classloader
043        * @param urn the resource urn
044        * @param path the resource path
045        * @exception IOException if an I/O error occurs
046        */
047        public AntlibStrategy( ClassLoader classloader, String urn, String path )
048          throws IOException
049        {
050            super( classloader );
051            if( null == urn )
052            {
053                throw new NullPointerException( "urn" );
054            }
055            if( null == path )
056            {
057                throw new NullPointerException( "path" );
058            }
059            m_urn = urn;
060            m_path = path;
061        }
062        
063        public String getName()
064        {
065            return m_urn;
066        }
067        
068        public int getPriority()
069        {
070            return 0;
071        }
072    
073       /**
074        * Return the part content or null if the result type is unresolvable 
075        * relative to the supplied classes argument. Class arguments recognized
076        * over an above plugin include the URL and String classes.  If the URL
077        * class is supplied a URL referencing the resource identified by path 
078        * is returned.  If a String is requested the urn value is returned.
079        *
080        * @param c the content class
081        * @return the content
082        * @exception IOException if an IO error occurs
083        */
084        public <T>T getContentForClass( Class<T> c ) throws IOException
085        {
086            if( Strategy.class.equals( c ) )
087            {
088                return c.cast( this );
089            }
090            else if( URL.class.equals( c ) )
091            {
092                URL url = getClassLoader().getResource( m_path );
093                return c.cast( url );
094            }
095            else if( String.class.equals( c ) )
096            {
097                String urn = getURN();
098                return c.cast( urn );
099            }
100            else
101            {
102                return null;
103            }
104        }
105        
106       /**
107        * Get the resource urn.
108        * @return the urn
109        */
110        public String getURN()
111        {
112            return m_urn;
113        }
114        
115       /**
116        * Get the resource path.
117        * @return the path
118        */ 
119        public String getPath()
120        {
121            return m_path;
122        }
123        
124        public boolean isaCandidate( Class<?> type )
125        {
126            throw new UnsupportedOperationException();
127        }
128    
129        public void initialize( ServiceRegistry registry )
130        {
131            // not required
132        }
133    
134       /**
135        * Instantiate a value.
136        * @param type the return type
137        * @return the resolved instance
138        */
139        public <T>T getInstance( Class<T> type )
140        {
141            try
142            {
143                ClassLoader classloader = getClassLoader();
144                Object resource = classloader.getResource( m_path );
145                return type.cast( resource );
146            }
147            catch( Exception e )
148            {
149                throw new PartError( e.getMessage(), e.getCause() );
150            }
151        }
152        
153       /**
154        * Encode the resource strategy to XML.
155        * @param buffer the output buffer
156        * @param key the key
157        * @exception IOException if an I/O error occurs
158        */
159        public void encode( Buffer buffer, String key ) throws IOException
160        {
161            String urn = getURN();
162            String path = getPath();
163            buffer.nl( "<resource xmlns=\"" + AntlibStrategyHandler.NAMESPACE + "\"" );
164            if( null != key )
165            {
166                buffer.write( " key=\"" + key + "\"" );
167            }
168            buffer.write( " urn=\"" + urn + "\" " );
169            buffer.write( " path=\"" + path + "\"" );
170            buffer.write( "/>" );
171        }
172        
173       /**
174        * Test if this instance is equal to the supplied instance.
175        * @param other the supplied instance
176        * @return the equality status
177        */
178        public boolean equals( Object other )
179        {
180            if( other instanceof AntlibStrategy )
181            {
182                AntlibStrategy resource = (AntlibStrategy) other;
183                if( !m_path.equals( resource.m_path ) )
184                {
185                    return false;
186                }
187                else
188                {
189                    return m_urn.equals( resource.m_urn );
190                }
191            }
192            else
193            {
194                return false;
195            }
196        }
197        
198       /**
199        * Get the hashcode for this instance.
200        * @return the hash value
201        */
202        public int hashCode()
203        {
204            int hash = 99875845;
205            hash ^= m_path.hashCode();
206            hash ^= m_urn.hashCode();
207            return hash;
208        }
209    }