/*
* Copyright 2003-2011 JetBrains s.r.o.
*
* 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 jetbrains.mps.vfs.impl;
import jetbrains.mps.vfs.IFile;
import jetbrains.mps.vfs.path.Path;
import jetbrains.mps.vfs.path.UniPath;
import jetbrains.mps.vfs.openapi.FileSystem;
import jetbrains.mps.vfs.ex.IFileEx;
import org.jetbrains.annotations.NotNull;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* IFile implementation via {@link java.io.File}
* TODO rewrite using {@link Path}.
*/
public class IoFile implements IFileEx {
@NotNull private File myFile; // always absolute
private final static IoFileSystem ourFS = IoFileSystem.INSTANCE;
public IoFile(@NotNull String path) {
this(path, ourFS);
}
IoFile(@NotNull String path, IoFileSystem fileSystem) {
this(new File(path), fileSystem);
}
IoFile(@NotNull File file, IoFileSystem fileSystem) {
myFile = file.getAbsoluteFile();
}
public IoFile(@NotNull UniPath path) {
this(path.toString());
}
@NotNull
@Override
public FileSystem getFileSystem() {
return ourFS;
}
@NotNull
@Override
public String getName() {
return myFile.getName();
}
@Override
public IFile getParent() {
File parentFile = myFile.getParentFile();
if (parentFile == null) {
return null;
}
return new IoFile(parentFile, ourFS);
}
@Override
public boolean isDirectory() {
return myFile.isDirectory();
}
@NotNull
@Override
public String getPath() {
return toSystemIndependentName(myFile.getAbsolutePath());
}
@NotNull
@Override
public UniPath toPath() {
return UniPath.fromString(myFile.getPath());
}
@NotNull
private static String toSystemIndependentName(@NotNull String aFileName) {
return aFileName.replace(File.separatorChar, Path.UNIX_SEPARATOR_CHAR).replace('\\', Path.UNIX_SEPARATOR_CHAR);
}
@Override
public URL getUrl() throws MalformedURLException {
return myFile.toURI().toURL();
}
@Override
public long lastModified() {
return myFile.lastModified();
}
@Override
public boolean exists() {
return myFile.exists();
}
@Override
public boolean mkdirs() {
return myFile.mkdirs();
}
@Override
public boolean createNewFile() {
try {
File parentFile = myFile.getParentFile();
if (parentFile.exists()) {
if (!parentFile.isDirectory()) {
return false;
}
} else {
if (!parentFile.mkdirs()) {
return false;
}
}
if (myFile.exists()) {
return myFile.isFile();
}
return myFile.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public boolean delete() {
List<IFile> children = getChildren();
if (children != null) {
children.forEach(IFile::delete);
}
return myFile.delete();
}
private boolean renameOrMove(File newIoFile) {
if (myFile.renameTo(newIoFile)) {
myFile = newIoFile;
return true;
} else {
return false;
}
}
@Override
public boolean rename(String newName) {
return renameOrMove(new File(myFile.getParentFile(), newName));
}
@Override
public boolean move(IFile newParent) {
return renameOrMove(new File(new File(newParent.getPath()), myFile.getName()));
}
@Override
public List<IFile> getChildren() {
File[] files = myFile.listFiles();
if (files == null) {
return Collections.emptyList();
}
List<IFile> result = new ArrayList<IFile>(files.length);
for (File f : files) {
result.add(new IoFile(f, ourFS));
}
return result;
}
@Override
@NotNull
public IFile getDescendant(@NotNull String suffix) {
return new IoFile(new File(myFile, suffix), ourFS);
}
@Override
public boolean isArchive() {
return myFile.getAbsolutePath().endsWith(".jar");
}
@Override
public boolean isInArchive() {
return false;
}
@Override
public InputStream openInputStream() throws IOException {
return new FileInputStream(myFile);
}
@Override
public OutputStream openOutputStream() throws IOException {
if (myFile.exists() && myFile.isHidden()) {
if (!myFile.delete()) {
throw new RuntimeException();
}
}
createNewFile();
return new FileOutputStream(myFile);
}
@Override
public boolean isReadOnly() {
return false;
}
@Override
public long length() {
return myFile.length();
}
public int hashCode() {
return myFile.hashCode();
}
public boolean equals(Object obj) {
if (!(obj instanceof IoFile)) {
return false;
}
IoFile ioFile = (IoFile) obj;
return ioFile.myFile.equals(myFile);
}
public String toString() {
return myFile.toString();
}
@Override
public IFile getBundleHome() {
return getParent();
}
@Override
public boolean setTimeStamp(long time) {
return myFile.setLastModified(time);
}
}