001 /*
002 * Copyright (C) 2010 eXo Platform SAS.
003 *
004 * This is free software; you can redistribute it and/or modify it
005 * under the terms of the GNU Lesser General Public License as
006 * published by the Free Software Foundation; either version 2.1 of
007 * the License, or (at your option) any later version.
008 *
009 * This software is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public
015 * License along with this software; if not, write to the Free
016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018 */
019
020 package org.crsh.vfs;
021
022 import org.crsh.util.IO;
023 import org.slf4j.Logger;
024 import org.slf4j.LoggerFactory;
025
026 import java.io.IOException;
027 import java.io.InputStream;
028 import java.net.URL;
029 import java.net.URLConnection;
030 import java.util.ArrayList;
031 import java.util.Collections;
032 import java.util.LinkedHashMap;
033 import java.util.LinkedList;
034 import java.util.List;
035
036 /**
037 * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
038 * @version $Revision$
039 */
040 public final class File {
041
042 /** . */
043 private static final Logger log = LoggerFactory.getLogger(Resource.class);
044
045 /** . */
046 private final FS fs;
047
048 /** . */
049 private final Path path;
050
051 /** . */
052 private LinkedList<Handle<?>> handles;
053
054 /** . */
055 private LinkedHashMap<Key, File> children;
056
057 public File(FS fs, Path path) {
058 this.fs = fs;
059 this.path = path;
060 this.handles = null;
061 }
062
063 public Path getPath() {
064 return path;
065 }
066
067 public boolean isDir() {
068 return path.isDir();
069 }
070
071 public String getName() {
072 return path.getName();
073 }
074
075 public Resource getResource() throws IOException {
076 try {
077 URL url = getURL();
078 if (url == null) {
079 log.warn("Could not obtain resource " + path);
080 } else {
081 URLConnection conn = url.openConnection();
082 long timestamp = conn.getLastModified();
083 InputStream in = url.openStream();
084 String content = IO.readAsUTF8(in);
085 return new Resource(content, timestamp, url);
086 }
087 }
088 catch (IOException e) {
089 log.warn("Could not retrieve resource " + path, e);
090 }
091 return null;
092 }
093
094 public URL getURL() throws IOException {
095 if (path.isDir()) {
096 throw new IllegalStateException("Cannot get url of a dir");
097 }
098 Handle handle = getHandles().peekFirst();
099 return handle != null ? handle.url() : null;
100
101 }
102
103 public Iterable<URL> getURLs() throws IOException {
104 if (path.isDir()) {
105 throw new IllegalStateException("Cannot get url of a dir");
106 }
107 List<URL> urls = Collections.emptyList();
108 for (Handle handle : getHandles()) {
109 if (urls.isEmpty()) {
110 urls = new ArrayList<URL>();
111 }
112 URL url = handle.url();
113 urls.add(url);
114 }
115 return urls;
116 }
117
118 public File child(String name, boolean dir) throws IOException {
119 if (children == null) {
120 children();
121 }
122 return children.get(new Key(name, dir));
123 }
124
125 public Iterable<File> children() throws IOException {
126 if (children == null) {
127 LinkedHashMap<Key, File> children = new LinkedHashMap<Key, File>();
128 for (Handle<?> handle : getHandles()) {
129 for (Handle<?> childHandle : handle.children()) {
130 File child = children.get(childHandle.key);
131 if (child == null) {
132 child = new File(fs, Path.get(path, childHandle.key.name, childHandle.key.dir));
133 children.put(childHandle.key, child);
134 }
135 if (child.handles == null) {
136 child.handles = new LinkedList<Handle<?>>();
137 }
138 child.handles.add(childHandle);
139 }
140 }
141 this.children = children;
142 }
143 return children.values();
144 }
145
146 LinkedList<Handle<?>> getHandles() {
147 if (handles == null) {
148 LinkedList<Handle<?>> handles = new LinkedList<Handle<?>>();
149 for (Mount<?> mount : fs.mounts) {
150 Handle<?> handle = null;
151 try {
152 handle = mount.getHandle(path);
153 }
154 catch (IOException e) {
155 e.printStackTrace();
156 }
157 if (handle != null) {
158 handles.add(handle);
159 }
160 }
161 this.handles = handles;
162 }
163 return handles;
164 }
165
166 @Override
167 public String toString() {
168 return "File[path=" + path.getValue() + "]";
169 }
170 }