/*******************************************************************************
* Copyright (c) 2012-2015 Codenvy, S.A.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.api.vfs.server;
import org.eclipse.che.api.core.ConflictException;
import org.eclipse.che.api.core.ForbiddenException;
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.vfs.shared.ItemType;
import org.eclipse.che.api.vfs.shared.PropertyFilter;
import org.eclipse.che.api.vfs.shared.dto.File;
import org.eclipse.che.api.vfs.shared.dto.Item;
import org.eclipse.che.api.vfs.shared.dto.ItemList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
/**
* Connection to virtual file system. Instances of this class are not safe to be used by multiple concurrent threads.
*
* @author <a href="mailto:aparfonov@exoplatform.com">Andrey Parfonov</a>
*/
public final class VirtualFileSystemURLConnection extends URLConnection {
private static final Logger LOG = LoggerFactory.getLogger(VirtualFileSystemURLConnection.class);
private final VirtualFileSystemRegistry registry;
private VirtualFileSystem vfs;
private Item item;
/**
* @param url
* the URL
* @param registry
* virtual file system registry
*/
public VirtualFileSystemURLConnection(URL url, VirtualFileSystemRegistry registry) {
super(check(url)); // Be sure URL is correct.
this.registry = registry;
}
private static URL check(URL url) {
if (!"ide+vfs".equals(url.getProtocol())) {
throw new IllegalArgumentException("Invalid URL: " + url);
}
return url;
}
/** @see java.net.URLConnection#connect() */
@Override
public void connect() throws IOException {
final URI theUri = URI.create(getURL().toString());
final String path = theUri.getPath();
final String vfsId =
(path == null || "/".equals(path)) ? null : (path.startsWith("/")) ? path.substring(1) : path;
try {
vfs = registry.getProvider(vfsId).newInstance(null);
final String itemIdentifier = theUri.getFragment();
item = (itemIdentifier.startsWith("/")) //
? vfs.getItemByPath(itemIdentifier, null, false, PropertyFilter.NONE_FILTER) //
: vfs.getItem(itemIdentifier, false, PropertyFilter.NONE_FILTER);
} catch (ForbiddenException | NotFoundException | ServerException e) {
throw new IOException(e.getMessage(), e);
}
connected = true;
}
public void disconnect() {
item = null;
vfs = null;
connected = false;
}
/** @see java.net.URLConnection#getContentLength() */
@Override
public int getContentLength() {
try {
if (!connected) {
connect();
}
if (item.getItemType() == ItemType.FILE) {
return (int)((File)item).getLength();
}
} catch (IOException e) {
if (LOG.isDebugEnabled()) {
LOG.debug(e.getMessage(), e);
}
}
return -1;
}
/** @see java.net.URLConnection#getContentType() */
@Override
public String getContentType() {
try {
if (!connected) {
connect();
}
return item.getMimeType();
} catch (IOException e) {
if (LOG.isDebugEnabled()) {
LOG.debug(e.getMessage(), e);
}
}
return null;
}
/** @see java.net.URLConnection#getLastModified() */
@Override
public long getLastModified() {
try {
if (!connected) {
connect();
}
if (item.getItemType() == ItemType.FILE) {
return ((File)item).getLastModificationDate();
}
} catch (IOException e) {
if (LOG.isDebugEnabled()) {
LOG.debug(e.getMessage(), e);
}
}
return 0;
}
/** @see java.net.URLConnection#getContent() */
@Override
public Object getContent() throws IOException {
if (!connected) {
connect();
}
return item;
}
/** @see java.net.URLConnection#getContent(java.lang.Class[]) */
@SuppressWarnings("rawtypes")
@Override
public Object getContent(Class[] classes) throws IOException {
throw new UnsupportedOperationException();
}
/** @see java.net.URLConnection#getInputStream() */
@Override
public InputStream getInputStream() throws IOException {
if (!connected) {
connect();
}
try {
if (item.getItemType() == ItemType.FILE) {
ContentStream content = vfs.getContent(item.getId());
return content.getStream();
}
// Folder. Show plain list of child.
ItemList children = vfs.getChildren(item.getId(), -1, 0, null, false, PropertyFilter.NONE_FILTER);
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer w = new OutputStreamWriter(out);
for (Item i : children.getItems()) {
w.write(i.getName());
w.write('\n');
}
w.flush();
w.close();
return new ByteArrayInputStream(out.toByteArray());
} catch (ForbiddenException | ConflictException | NotFoundException | ServerException e) {
throw new IOException(e.getMessage(), e);
}
}
}