/* * Copyright 2010 the original author or authors. * * 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. */ package org.gradle.api.internal.file; import org.gradle.api.InvalidUserDataException; import org.gradle.api.Nullable; import org.gradle.api.PathValidation; import org.gradle.api.file.FileCollection; import org.gradle.api.file.FileTree; import org.gradle.api.internal.file.collections.DefaultConfigurableFileCollection; import org.gradle.api.resources.internal.ReadableResourceInternal; import org.gradle.api.tasks.util.PatternSet; import org.gradle.internal.Cast; import org.gradle.internal.Factory; import org.gradle.internal.exceptions.DiagnosticsVisitor; import org.gradle.internal.nativeintegration.filesystem.FileSystem; import org.gradle.internal.typeconversion.NotationParser; import org.gradle.internal.typeconversion.UnsupportedNotationException; import org.gradle.util.CollectionUtils; import org.gradle.util.GFileUtils; import java.io.File; import java.net.URI; import java.util.List; public abstract class AbstractFileResolver implements FileResolver { private final FileSystem fileSystem; private final NotationParser<Object, Object> fileNotationParser; private final Factory<PatternSet> patternSetFactory; private final FileNormaliser fileNormaliser; protected AbstractFileResolver(FileSystem fileSystem, Factory<PatternSet> patternSetFactory) { this.fileSystem = fileSystem; this.fileNormaliser = new FileNormaliser(fileSystem); this.fileNotationParser = FileOrUriNotationConverter.parser(fileSystem); this.patternSetFactory = patternSetFactory; } public FileSystem getFileSystem() { return fileSystem; } public FileResolver withBaseDir(Object path) { return new BaseDirFileResolver(fileSystem, resolve(path), patternSetFactory); } public File resolve(Object path) { return resolve(path, PathValidation.NONE); } public NotationParser<Object, File> asNotationParser() { return new NotationParser<Object, File>() { public File parseNotation(Object notation) throws UnsupportedNotationException { // TODO Further differentiate between unsupported notation errors and others (particularly when we remove the deprecated 'notation.toString()' resolution) return resolve(notation, PathValidation.NONE); } @Override public void describe(DiagnosticsVisitor visitor) { visitor.candidate("Anything that can be converted to a file, as per Project.file()"); } }; } public File resolve(Object path, PathValidation validation) { File file = doResolve(path); file = fileNormaliser.normalise(file); validate(file, validation); return file; } public Factory<File> resolveLater(final Object path) { return new Factory<File>() { public File create() { return resolve(path); } }; } public URI resolveUri(Object path) { return convertObjectToURI(path); } protected abstract File doResolve(Object path); protected URI convertObjectToURI(Object path) { Object object = GFileUtils.unpack(path); Object converted = fileNotationParser.parseNotation(object); if (converted instanceof File) { return resolve(converted).toURI(); } return (URI) converted; } @Nullable protected File convertObjectToFile(Object path) { Object object = GFileUtils.unpack(path); if (object == null) { return null; } Object converted = fileNotationParser.parseNotation(object); if (converted instanceof File) { return (File) converted; } throw new InvalidUserDataException(String.format("Cannot convert URL '%s' to a file.", converted)); } protected void validate(File file, PathValidation validation) { switch (validation) { case NONE: break; case EXISTS: if (!file.exists()) { throw new InvalidUserDataException(String.format("File '%s' does not exist.", file)); } break; case FILE: if (!file.exists()) { throw new InvalidUserDataException(String.format("File '%s' does not exist.", file)); } if (!file.isFile()) { throw new InvalidUserDataException(String.format("File '%s' is not a file.", file)); } break; case DIRECTORY: if (!file.exists()) { throw new InvalidUserDataException(String.format("Directory '%s' does not exist.", file)); } if (!file.isDirectory()) { throw new InvalidUserDataException(String.format("Directory '%s' is not a directory.", file)); } break; } } public FileCollectionInternal resolveFiles(Object... paths) { if (paths.length == 1 && paths[0] instanceof FileCollection) { return Cast.cast(FileCollectionInternal.class, paths[0]); } return new DefaultConfigurableFileCollection(this, null, paths); } public FileTreeInternal resolveFilesAsTree(Object... paths) { return Cast.cast(FileTreeInternal.class, resolveFiles(paths).getAsFileTree()); } public FileTreeInternal compositeFileTree(List<? extends FileTree> fileTrees) { return new DefaultCompositeFileTree(CollectionUtils.checkedCast(FileTreeInternal.class, fileTrees)); } public ReadableResourceInternal resolveResource(Object path) { if (path instanceof ReadableResourceInternal) { return (ReadableResourceInternal) path; } return new FileResource(resolve(path)); } @Override public Factory<PatternSet> getPatternSetFactory() { return patternSetFactory; } }