001    /*
002     * Copyright 2005 Niclas Hedhman
003     * Copyright 2005 Stephen J. McConnell.
004     *
005     * Licensed  under the  Apache License,  Version 2.0  (the "License");
006     * you may not use  this file  except in  compliance with the License.
007     * You may obtain a copy of the License at
008     *
009     *   http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed  under the  License is distributed on an "AS IS" BASIS,
013     * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
014     * implied.
015     *
016     * See the License for the specific language governing permissions and
017     * limitations under the License.
018     */
019    
020    package net.dpml.transit.link;
021    
022    import java.io.IOException;
023    import java.io.InputStream;
024    import java.io.OutputStream;
025    import java.net.URI;
026    import java.net.URL;
027    import java.net.URLConnection;
028    import java.security.AccessController;
029    import java.security.PrivilegedExceptionAction;
030    import java.security.PrivilegedActionException;
031    import java.security.PrivilegedAction;
032    
033    import net.dpml.transit.Transit;
034    import net.dpml.transit.Artifact;
035    import net.dpml.transit.UnsupportedSchemeException;
036    import net.dpml.util.MimeTypeHandler;
037    
038    /**
039     * link: URL protocol connection processor.
040     * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
041     * @version 1.0.3
042     */
043    public class LinkURLConnection extends URLConnection
044    {
045        private boolean m_connected;
046        private URL     m_targetURL;
047    
048        /**
049         * Creation of a new handler.
050         * @param url the url to establish a connection with
051         * @exception NullPointerException if the url argument is null
052         */
053        LinkURLConnection( URL url )
054            throws NullPointerException
055        {
056            super( url );
057            m_connected = false;
058        }
059    
060       /**
061        * Establish a connection.
062        *
063        * @exception IOException is an error occurs while attempting to establish
064        *  the connection.
065        */
066        public void connect()
067            throws IOException
068        {
069            if( m_connected )
070            {
071                return;
072            }
073    
074            m_connected = true;
075            
076            try
077            {
078                AccessController.doPrivileged( 
079                  new PrivilegedExceptionAction()
080                  {
081                    public Object run()
082                        throws IOException
083                    {
084                        URI linkUri = URI.create( url.toExternalForm() );
085                        LinkManager manager = Transit.getInstance().getLinkManager();
086                        URI targetUri = manager.getTargetURI( linkUri );
087                        if( targetUri != null )
088                        {
089                            try
090                            {
091                                Artifact artifact = Artifact.createArtifact( targetUri );
092                                m_targetURL = artifact.toURL();
093                            }
094                            catch( UnsupportedSchemeException use )
095                            {
096                                m_targetURL = new URL( targetUri.toASCIIString() );
097                            }
098                        }
099                        else
100                        {
101                            m_targetURL = null;
102                        }
103                        return null; // nothing to return
104                    }
105                  }
106                );
107            } 
108            catch( PrivilegedActionException e )
109            {
110                throw (IOException) e.getException();
111            } 
112        }
113    
114       /**
115        * Return an input stream to the resource.
116        * @return the input stream
117        * @exception IOException is an error occurs
118        */
119        public InputStream getInputStream()
120            throws IOException
121        {
122            connect();
123            if( m_targetURL == null )
124            {
125                return null;
126            }
127            else
128            {
129                URLConnection conn = m_targetURL.openConnection();
130                InputStream in = conn.getInputStream();
131                return in;
132            }
133        }
134    
135       /**
136        * Return an output stream to the resource.
137        * @return the output stream
138        * @exception IOException if any I/O problems occur.
139        */
140        public OutputStream getOutputStream()
141            throws IOException
142        {
143            connect();
144            if( m_targetURL == null )
145            {
146                return null;
147            }
148            else
149            {
150                URLConnection conn = m_targetURL.openConnection();
151                OutputStream out = conn.getOutputStream();
152                return out;
153            }
154        }
155    
156       /**
157        * Reutrn the mimetype of the content.
158        * @return the content mimetype
159        */
160        public String getContentType()
161        {
162            return MimeTypeHandler.getMimeType( "link" );
163        }
164    
165       /**
166        * Return the content for this Link.
167        * @param classes a sequence of classes against which the
168        *   implementation will attempt to establish a known match
169        * @return the content object (possibly null)
170        * @exception IOException is an error occurs
171        */
172        public Object getContent( final Class[] classes )
173            throws IOException
174        {
175            final LinkManager manager = Transit.getInstance().getLinkManager();
176    
177            Object result = AccessController.doPrivileged( 
178              new PrivilegedAction()
179              {
180                public Object run()
181                {
182                    for( int i=0; i < classes.length; i++ )
183                    {
184                        Class c = classes[i];
185                        if( c.equals( Link.class ) )
186                        {
187                            String extUri = getURL().toString();
188                            URI uri = URI.create( extUri );
189                            Link link = new Link( uri, manager );
190                            return link;
191                        }
192                        if( c.equals( URI.class ) )
193                        {
194                            String extUri = getURL().toString();
195                            URI uri = URI.create( extUri );
196                            return uri;
197                        }
198                    }
199                    return null;
200                }
201              }
202            );
203    
204            if( null != result )
205            {
206                return result;
207            }
208            else
209            {
210                connect();
211                if( null != m_targetURL )
212                {
213                    return m_targetURL.getContent( classes );
214                }
215                else
216                {
217                    return super.getContent( classes );
218                }
219            }
220        }
221    }