use less space for storing children of a CoreJarVirtualFile, since most files don...
[idea/community.git] / platform / core-impl / src / com / intellij / openapi / vfs / impl / jar / CoreJarVirtualFile.java
1 /*
2  * Copyright 2000-2015 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.openapi.vfs.impl.jar;
17
18 import com.intellij.openapi.util.Couple;
19 import com.intellij.openapi.util.io.BufferExposingByteArrayInputStream;
20 import com.intellij.openapi.util.io.FileAttributes;
21 import com.intellij.openapi.vfs.VirtualFile;
22 import com.intellij.openapi.vfs.VirtualFileSystem;
23 import com.intellij.util.SmartList;
24 import org.jetbrains.annotations.NotNull;
25 import org.jetbrains.annotations.Nullable;
26
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.OutputStream;
30 import java.util.List;
31
32 /**
33  * @author yole
34  */
35 public class CoreJarVirtualFile extends VirtualFile {
36   private final CoreJarHandler myHandler;
37   private final String myName;
38   private final FileAttributes myEntry;
39   private final VirtualFile myParent;
40   private List<VirtualFile> myChildren = null;
41
42   public CoreJarVirtualFile(@NotNull CoreJarHandler handler, @NotNull String name, @NotNull FileAttributes entry, @Nullable CoreJarVirtualFile parent) {
43     myHandler = handler;
44     myName = name;
45     myEntry = entry;
46     myParent = parent;
47
48     if (parent != null) {
49       if (parent.myChildren == null) {
50         parent.myChildren = new SmartList<VirtualFile>();
51       }
52       parent.myChildren.add(this);
53     }
54   }
55
56   @NotNull
57   @Override
58   public String getName() {
59     return myName;
60   }
61
62   @NotNull
63   @Override
64   public VirtualFileSystem getFileSystem() {
65     return myHandler.getFileSystem();
66   }
67
68   @Override
69   @NotNull
70   public String getPath() {
71     if (myParent == null) return myHandler.getFile().getPath() + "!/";
72
73     String parentPath = myParent.getPath();
74     StringBuilder answer = new StringBuilder(parentPath.length() + 1 + myName.length());
75     answer.append(parentPath);
76     if (answer.charAt(answer.length() - 1) != '/') {
77       answer.append('/');
78     }
79     answer.append(myName);
80
81     return answer.toString();
82   }
83
84   @Override
85   public boolean isWritable() {
86     return false;
87   }
88
89   @Override
90   public boolean isDirectory() {
91     return myEntry.isDirectory();
92   }
93
94   @Override
95   public boolean isValid() {
96     return true;
97   }
98
99   @Override
100   public VirtualFile getParent() {
101     return myParent;
102   }
103
104   @Override
105   public VirtualFile[] getChildren() {
106     if (myChildren == null) {
107       return VirtualFile.EMPTY_ARRAY;
108     }
109     return myChildren.toArray(new VirtualFile[myChildren.size()]);
110   }
111
112   @NotNull
113   @Override
114   public OutputStream getOutputStream(Object requestor, long newModificationStamp, long newTimeStamp) throws IOException {
115     throw new UnsupportedOperationException("JarFileSystem is read-only");
116   }
117
118   @NotNull
119   @Override
120   public byte[] contentsToByteArray() throws IOException {
121     Couple<String> pair = ((CoreJarFileSystem)getFileSystem()).splitPath(getPath());
122     return myHandler.contentsToByteArray(pair.second);
123   }
124
125   @Override
126   public long getTimeStamp() {
127     return myEntry.lastModified;
128   }
129
130   @Override
131   public long getLength() {
132     return myEntry.length;
133   }
134
135   @Override
136   public void refresh(boolean asynchronous, boolean recursive, Runnable postRunnable) { }
137
138   @Override
139   public InputStream getInputStream() throws IOException {
140     return new BufferExposingByteArrayInputStream(contentsToByteArray());
141   }
142
143   @Override
144   public long getModificationStamp() {
145     return 0;
146   }
147 }