package org.codehaus.plexus.components.io.resources; /* * Copyright 2007 The Codehaus Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.DeferredFileOutputStream; import org.codehaus.plexus.components.io.attributes.Java7AttributeUtils; import org.codehaus.plexus.components.io.attributes.Java7Reflector; import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes; import org.codehaus.plexus.components.io.functions.ContentSupplier; import org.codehaus.plexus.components.io.functions.FileSupplier; import org.codehaus.plexus.components.io.functions.InputStreamTransformer; import org.codehaus.plexus.components.io.functions.ResourceAttributeSupplier; import javax.annotation.Nonnull; /** * Implementation of {@link PlexusIoResource} for files. */ public class PlexusIoFileResource extends AbstractPlexusIoResource implements ResourceAttributeSupplier, FileSupplier { @Nonnull private final File file; @Nonnull private final PlexusIoResourceAttributes attributes; private final ContentSupplier contentSupplier; private final DeferredFileOutputStream dfos; protected PlexusIoFileResource( @Nonnull File file, @Nonnull String name, @Nonnull PlexusIoResourceAttributes attrs ) throws IOException { this( file, name, attrs, null, null ); } @SuppressWarnings( "ConstantConditions" ) PlexusIoFileResource( @Nonnull final File file, @Nonnull String name, @Nonnull PlexusIoResourceAttributes attrs, final ContentSupplier contentSupplier, final InputStreamTransformer streamTransformer ) throws IOException { super( name, file.lastModified(), file.length(), file.isFile(), file.isDirectory(), file.exists() ); this.file = file; this.contentSupplier = contentSupplier != null ? contentSupplier : getRootContentSupplier( file ); boolean hasTransformer = streamTransformer != null && streamTransformer != identityTransformer; InputStreamTransformer transToUse = streamTransformer != null ? streamTransformer : identityTransformer; dfos = hasTransformer && file.isFile() ? asDeferredStream( this.contentSupplier, transToUse, this ) : null; if (attrs == null) throw new IllegalArgumentException( "attrs is null for file " + file.getName() ); this.attributes = attrs; } private static DeferredFileOutputStream asDeferredStream( @Nonnull ContentSupplier supplier, @Nonnull InputStreamTransformer transToUse, PlexusIoResource resource ) throws IOException { DeferredFileOutputStream dfos = new DeferredFileOutputStream( 5000000, "p-archiver", null, null ); InputStream inputStream = supplier.getContents(); InputStream transformed = transToUse.transform( resource, inputStream ); IOUtils.copy( transformed, dfos ); IOUtils.closeQuietly( inputStream ); IOUtils.closeQuietly( transformed ); return dfos; } private static ContentSupplier getRootContentSupplier(final File file){ return new ContentSupplier() { public InputStream getContents() throws IOException { return new FileInputStream( file); } }; } public static String getName( File file ) { return file.getPath().replace( '\\', '/' ); } /** * Returns the resources file. */ @Nonnull public File getFile() { return file; } @Nonnull public InputStream getContents() throws IOException { if ( dfos == null ) { return contentSupplier.getContents(); } if ( dfos.isInMemory() ) { return new ByteArrayInputStream( dfos.getData() ); } else { return new FileInputStream( dfos.getFile() ) { @SuppressWarnings( "ResultOfMethodCallIgnored" ) @Override public void close() throws IOException { super.close(); dfos.getFile().delete(); } }; } } @Nonnull public URL getURL() throws IOException { return getFile().toURI().toURL(); } public long getSize() { if ( dfos == null ) { return getFile().length(); } if ( dfos.isInMemory() ) { return dfos.getByteCount(); } else { return dfos.getFile().length(); } } public boolean isDirectory() { return getFile().isDirectory(); } public boolean isExisting() { return getFile().exists(); } public boolean isFile() { return getFile().isFile(); } @Nonnull public PlexusIoResourceAttributes getAttributes() { return attributes; } public long getLastModified() { if ( Java7Reflector.isAtLeastJava7() ) { return Java7AttributeUtils.getLastModified( getFile() ); } else { return getFile().lastModified(); } } @Override public boolean isSymbolicLink() { return getAttributes().isSymbolicLink(); } private static final InputStreamTransformer identityTransformer = AbstractPlexusIoResourceCollection.identityTransformer; }