001package org.apache.maven.wagon;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.File;
023import java.io.InputStream;
024import java.io.OutputStream;
025
026import org.apache.maven.wagon.authorization.AuthorizationException;
027import org.apache.maven.wagon.events.TransferEvent;
028import org.apache.maven.wagon.resource.Resource;
029import org.codehaus.plexus.util.IOUtil;
030
031/**
032 * Base class for wagon which provide stream based API.
033 *
034 * @author <a href="mailto:michal@codehaus.org">Michal Maczka</a>
035 *
036 */
037public abstract class StreamWagon
038    extends AbstractWagon
039    implements StreamingWagon
040{
041    // ----------------------------------------------------------------------
042    //
043    // ----------------------------------------------------------------------
044
045    public abstract void fillInputData( InputData inputData )
046        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException;
047
048    public abstract void fillOutputData( OutputData outputData )
049        throws TransferFailedException;
050
051    public abstract void closeConnection()
052        throws ConnectionException;
053
054    // ----------------------------------------------------------------------
055    //
056    // ----------------------------------------------------------------------
057
058    public void get( String resourceName, File destination )
059        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
060    {
061        getIfNewer( resourceName, destination, 0 );
062    }
063
064    protected void checkInputStream( InputStream is, Resource resource )
065        throws TransferFailedException
066    {
067        if ( is == null )
068        {
069            TransferFailedException e =
070                new TransferFailedException( getRepository().getUrl()
071                    + " - Could not open input stream for resource: '" + resource + "'" );
072            fireTransferError( resource, e, TransferEvent.REQUEST_GET );
073            throw e;
074        }
075    }
076
077    public boolean getIfNewer( String resourceName, File destination, long timestamp )
078        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
079    {
080        boolean retValue = false;
081
082        Resource resource = new Resource( resourceName );
083
084        fireGetInitiated( resource, destination );
085
086        resource.setLastModified( timestamp );
087        
088        InputStream is = getInputStream( resource );
089
090        // always get if timestamp is 0 (ie, target doesn't exist), otherwise only if older than the remote file
091        if ( timestamp == 0 || timestamp < resource.getLastModified() )
092        {
093            retValue = true;
094
095            checkInputStream( is, resource );
096
097            getTransfer( resource, destination, is );
098        }
099        else
100        {
101            IOUtil.close( is );
102        }
103
104        return retValue;
105    }
106
107    protected InputStream getInputStream( Resource resource )
108        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
109    {
110        InputData inputData = new InputData();
111
112        inputData.setResource( resource );
113
114        try
115        {
116            fillInputData( inputData );
117        }
118        catch ( TransferFailedException e )
119        {
120            fireTransferError( resource, e, TransferEvent.REQUEST_GET );
121            cleanupGetTransfer( resource );
122            throw e;
123        }
124        catch ( ResourceDoesNotExistException e )
125        {
126            fireTransferError( resource, e, TransferEvent.REQUEST_GET );
127            cleanupGetTransfer( resource );
128            throw e;
129        }
130        catch ( AuthorizationException e )
131        {
132            fireTransferError( resource, e, TransferEvent.REQUEST_GET );
133            cleanupGetTransfer( resource );
134            throw e;
135        }
136        finally
137        {
138            if ( inputData.getInputStream() == null )
139            {
140                cleanupGetTransfer( resource );
141            }
142        }
143
144        return inputData.getInputStream();
145    }
146
147    // source doesn't exist exception
148    public void put( File source, String resourceName )
149        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
150    {
151        Resource resource = new Resource( resourceName );
152
153        firePutInitiated( resource, source );
154
155        resource.setContentLength( source.length() );
156
157        resource.setLastModified( source.lastModified() );
158
159        OutputStream os = getOutputStream( resource );
160
161        checkOutputStream( resource, os );
162
163        putTransfer( resource, source, os, true );
164    }
165
166    protected void checkOutputStream( Resource resource, OutputStream os )
167        throws TransferFailedException
168    {
169        if ( os == null )
170        {
171            TransferFailedException e =
172                new TransferFailedException( getRepository().getUrl()
173                    + " - Could not open output stream for resource: '" + resource + "'" );
174            fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
175            throw e;
176        }
177    }
178
179    protected OutputStream getOutputStream( Resource resource )
180        throws TransferFailedException
181    {
182        OutputData outputData = new OutputData();
183
184        outputData.setResource( resource );
185
186        try
187        {
188            fillOutputData( outputData );
189        }
190        catch ( TransferFailedException e )
191        {
192            fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
193
194            throw e;
195        }
196        finally
197        {
198            if ( outputData.getOutputStream() == null )
199            {
200                cleanupPutTransfer( resource );
201            }
202        }
203
204        return outputData.getOutputStream();
205    }
206
207    public boolean getIfNewerToStream( String resourceName, OutputStream stream, long timestamp )
208        throws ResourceDoesNotExistException, TransferFailedException, AuthorizationException
209    {
210        boolean retValue = false;
211
212        Resource resource = new Resource( resourceName );
213
214        fireGetInitiated( resource, null );
215
216        InputStream is = getInputStream( resource );
217
218        // always get if timestamp is 0 (ie, target doesn't exist), otherwise only if older than the remote file
219        if ( timestamp == 0 || timestamp < resource.getLastModified() )
220        {
221            retValue = true;
222
223            checkInputStream( is, resource );
224
225            fireGetStarted( resource, null );
226
227            getTransfer( resource, stream, is, true, Integer.MAX_VALUE );
228
229            fireGetCompleted( resource, null );
230        }
231        else
232        {
233            IOUtil.close( is );
234        }
235        
236        return retValue;
237    }
238
239    public void getToStream( String resourceName, OutputStream stream )
240        throws ResourceDoesNotExistException, TransferFailedException, AuthorizationException
241    {
242        getIfNewerToStream( resourceName, stream, 0 );
243    }
244
245    public void putFromStream( InputStream stream, String destination )
246        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
247    {
248        Resource resource = new Resource( destination );
249
250        firePutInitiated( resource, null );
251
252        putFromStream( stream, resource );
253    }
254
255    public void putFromStream( InputStream stream, String destination, long contentLength, long lastModified )
256        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
257    {
258        Resource resource = new Resource( destination );
259
260        firePutInitiated( resource, null );
261
262        resource.setContentLength( contentLength );
263
264        resource.setLastModified( lastModified );
265
266        putFromStream( stream, resource );
267    }
268
269    protected void putFromStream( InputStream stream, Resource resource )
270        throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
271    {
272        OutputStream os = getOutputStream( resource );
273
274        checkOutputStream( resource, os );
275
276        firePutStarted( resource, null );
277
278        putTransfer( resource, stream, os, true );
279
280        firePutCompleted( resource, null );
281    }
282}