summaryrefslogtreecommitdiffstats
path: root/sched/src/com/android/sched/vfs/InputOutputZipVDir.java
blob: 80f51b21bd26fe74dab40f319764b1a0a902d748 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * 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 com.android.sched.vfs;

import com.android.sched.util.ConcurrentIOException;
import com.android.sched.util.file.CannotCreateFileException;
import com.android.sched.util.file.CannotDeleteFileException;
import com.android.sched.util.file.NoSuchFileException;
import com.android.sched.util.file.NotFileOrDirectoryException;
import com.android.sched.util.location.DirectoryLocation;
import com.android.sched.util.location.FileLocation;
import com.android.sched.util.location.Location;
import com.android.sched.util.location.ZipLocation;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.zip.ZipEntry;

import javax.annotation.Nonnull;

/**
 * A directory in an {@link InputOutputZipVFS} VFS.
 */
class InputOutputZipVDir extends AbstractVElement implements InputOutputVDir {

  @Nonnull
  protected final File dir;
  @Nonnull
  protected final InputOutputZipVFS vfs;
  @Nonnull
  private final ZipEntry zipEntry;

  public InputOutputZipVDir(@Nonnull InputOutputZipVFS vfs, @Nonnull File dir,
      @Nonnull ZipEntry zipEntry) {
    this.vfs = vfs;
    this.dir = dir;
    this.zipEntry = zipEntry;
  }

  @Nonnull
  @Override
  public String getName() {
    return dir.getName();
  }

  @Nonnull
  @Override
  public synchronized Collection<? extends InputVElement> list() {
    File[] subs = dir.listFiles();
    if (subs == null) {
      throw new ConcurrentIOException(new ListDirException(dir));
    }
    if (subs.length == 0) {
      return Collections.emptyList();
    }

    ArrayList<InputVElement> items = new ArrayList<InputVElement>(subs.length);
    for (File sub : subs) {
      String subZipEntryName = zipEntry.getName() + sub.getName();
      if (sub.isFile()) {
        items.add(new InputOutputZipVFile(vfs, sub, new ZipEntry(subZipEntryName)));
      } else {
        items.add(new InputOutputZipVDir(vfs, sub,
            new ZipEntry(subZipEntryName + ZipUtils.ZIP_SEPARATOR)));
      }
    }

    return items;
  }

  @Override
  @Nonnull
  public Location getLocation() {
    return new ZipLocation(vfs.getLocation(), zipEntry);
  }

  @Override
  public boolean isVDir() {
    return true;
  }

  @Override
  @Nonnull
  public OutputVFile createOutputVFile(@Nonnull VPath path) throws CannotCreateFileException {
    assert !vfs.isClosed();
    File file = new File(dir, path.getPathAsString(ZipUtils.ZIP_SEPARATOR));
    if (!file.getParentFile().mkdirs() && !file.getParentFile().isDirectory()) {
      throw new CannotCreateFileException(new DirectoryLocation(file.getParentFile()));
    }

    assert !(path.equals(VPath.ROOT));
    String newEntryName = path.getPathAsString(ZipUtils.ZIP_SEPARATOR);
    String parentEntryName = zipEntry.getName();
    if (!parentEntryName.isEmpty()) {
      newEntryName = parentEntryName + newEntryName;
    }
    return new InputOutputZipVFile(vfs, file, new ZipEntry(newEntryName));
  }

  @Override
  @Nonnull
  public OutputVDir createOutputVDir(@Nonnull VPath path) throws CannotCreateFileException {
    assert !vfs.isClosed();
    File file = new File(dir, path.getPathAsString(ZipUtils.ZIP_SEPARATOR));
    if (!file.getParentFile().mkdirs() && !file.getParentFile().isDirectory()) {
      throw new CannotCreateFileException(new DirectoryLocation(file.getParentFile()));
    }

    if (!file.mkdir()) {
      throw new CannotCreateFileException(new DirectoryLocation(file));
    }

    assert !(path.equals(VPath.ROOT));
    String newEntryName = path.getPathAsString(ZipUtils.ZIP_SEPARATOR);
    String parentEntryName = zipEntry.getName();
    if (!parentEntryName.isEmpty()) {
      newEntryName = parentEntryName + newEntryName;
    }
    return new InputOutputZipVDir(vfs, file, new ZipEntry(newEntryName));
  }

  @Override
  @Nonnull
  public InputOutputVDir getInputVDir(@Nonnull VPath path) throws NotFileOrDirectoryException,
      NoSuchFileException {
    File file = new File(dir, path.getPathAsString(File.separatorChar));
    if (!file.exists()) {
      throw new NoSuchFileException(new FileLocation(file));
    }
    if (file.isFile()) {
      throw new NotFileOrDirectoryException(new FileLocation(file));
    }
    return new InputOutputZipVDir(vfs, file,
        new ZipEntry(path.getPathAsString(ZipUtils.ZIP_SEPARATOR) + ZipUtils.ZIP_SEPARATOR));
  }

  @Override
  @Nonnull
  public InputVFile getInputVFile(@Nonnull VPath path) throws NotFileOrDirectoryException,
      NoSuchFileException {
    File file = new File(dir, path.getPathAsString(File.separatorChar));
    if (!file.exists()) {
      throw new NoSuchFileException(new FileLocation(file));
    }
    if (!file.isFile()) {
      throw new NotFileOrDirectoryException(new FileLocation(file));
    }
    return new InputOutputZipVFile(vfs, file,
        new ZipEntry(path.getPathAsString(ZipUtils.ZIP_SEPARATOR)));
  }

  @Override
  @Nonnull
  public void delete(@Nonnull VPath path) throws CannotDeleteFileException {
    assert !vfs.isClosed();
    File file = new File(dir, path.getPathAsString(File.separatorChar));
    if (!file.delete()) {
      throw new CannotDeleteFileException(
          file.isDirectory() ? new DirectoryLocation(file) : new FileLocation(file));
    }
  }
}