/*
* RapidMiner
*
* Copyright (C) 2001-2011 by Rapid-I and the contributors
*
* Complete list of developers available at our web site:
*
* http://rapid-i.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.rapidminer.repository.remote;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import com.rapid_i.repository.wsimport.EntryResponse;
import com.rapid_i.repository.wsimport.FolderContentsResponse;
import com.rapid_i.repository.wsimport.Response;
import com.rapidminer.operator.IOObject;
import com.rapidminer.operator.Operator;
import com.rapidminer.repository.BlobEntry;
import com.rapidminer.repository.DataEntry;
import com.rapidminer.repository.Entry;
import com.rapidminer.repository.Folder;
import com.rapidminer.repository.IOObjectEntry;
import com.rapidminer.repository.MalformedRepositoryLocationException;
import com.rapidminer.repository.ProcessEntry;
import com.rapidminer.repository.RepositoryConstants;
import com.rapidminer.repository.RepositoryException;
import com.rapidminer.repository.RepositoryLocation;
import com.rapidminer.tools.ProgressListener;
/**
* @author Simon Fischer
*/
public class RemoteFolder extends RemoteEntry implements Folder {
private final Comparator<Entry> nameComparator = new Comparator<Entry>() {
@Override
public int compare(Entry o1, Entry o2) {
return o1.getName().compareTo(o2.getName());
}
};
private List<Folder> folders;
private List<DataEntry> entries;
private final Object lock = new Object();
private boolean readOnly = false;
private boolean forbidden = false;
RemoteFolder(String location) {
super(location);
}
RemoteFolder(EntryResponse response, RemoteFolder container, RemoteRepository repository) {
super(response, container, repository);
}
@Override
public Folder createFolder(String name) throws RepositoryException {
EntryResponse response = getRepository().getRepositoryService().makeFolder(getPath(), name);
if (response.getStatus() != RepositoryConstants.OK) {
throw new RepositoryException(response.getErrorMessage());
}
RemoteFolder newFolder = new RemoteFolder(response, this, getRepository());
if (folders != null) {
folders.add(newFolder);
Collections.sort(folders, nameComparator);
getRepository().fireEntryAdded(newFolder, this);
}
return newFolder;
}
@Override
public BlobEntry createBlobEntry(String name) throws RepositoryException {
EntryResponse response = getRepository().getRepositoryService().createBlob(getPath(), name);
RemoteBlobEntry newBlob= new RemoteBlobEntry(response, this, getRepository());
if (this.entries != null) {
entries.add(newBlob);
Collections.sort(entries, nameComparator);
getRepository().fireEntryAdded(newBlob, this);
}
return newBlob;
}
@Override
public List<DataEntry> getDataEntries() throws RepositoryException {
ensureLoaded();
return entries;
}
private void ensureLoaded() throws RepositoryException {
synchronized (lock) {
if (forbidden) {
return;
}
if ((entries == null) || (folders == null)) {
FolderContentsResponse response;
String path = getPath();
response = getRepository().getRepositoryService().getFolderContents(path);
entries = new LinkedList<DataEntry>();
folders = new LinkedList<Folder>();
if (response.getStatus() != RepositoryConstants.OK) {
if (response.getStatus() == RepositoryConstants.ACCESS_DENIED) {
readOnly = true;
forbidden = true;
} else {
getLogger().warning("Cannot get folder: "+response.getErrorMessage());
}
return;
}
for (EntryResponse entry : response.getEntries()) {
if (entry.getType().equals(Folder.TYPE_NAME)) {
folders.add(new RemoteFolder(entry, this, getRepository()));
} else if (entry.getType().equals(ProcessEntry.TYPE_NAME)) {
entries.add(new RemoteProcessEntry(entry, this, getRepository()));
} else if (entry.getType().equals(IOObjectEntry.TYPE_NAME)) {
entries.add(new RemoteIOObjectEntry(entry, this, getRepository()));
} else if (entry.getType().equals(BlobEntry.TYPE_NAME)) {
entries.add(new RemoteBlobEntry(entry, this, getRepository()));
} else {
getLogger().warning("Unknown entry type: "+entry.getType());
}
}
}
}
}
@Override
public List<Folder> getSubfolders() throws RepositoryException {
ensureLoaded();
return folders;
}
@Override
public String getType() {
return Folder.TYPE_NAME;
}
@Override
public boolean willBlock() {
return (folders == null) || (entries == null);
}
@Override
public void refresh() throws RepositoryException {
folders = null;
entries = null;
readOnly = false;
forbidden = false;
ensureLoaded();
getRepository().fireRefreshed(this);
}
@Override
public boolean containsEntry(String name) throws RepositoryException {
ensureLoaded();
for (Folder folder : folders) {
if (folder.getName().equals(name)) {
return true;
}
}
for (DataEntry entry : entries) {
if (entry.getName().equals(name)) {
return true;
}
}
return false;
}
@Override
public IOObjectEntry createIOObjectEntry(String name, IOObject ioobject, Operator callingOperator, ProgressListener l) throws RepositoryException {
RepositoryLocation loc;
try {
loc = new RepositoryLocation(getLocation(), name);
} catch (MalformedRepositoryLocationException e) {
throw new RepositoryException(e);
}
RemoteIOObjectEntry.storeData(ioobject, loc.getPath(), getRepository(), l);
EntryResponse response = getRepository().getRepositoryService().getEntry(loc.getPath());
if (response.getStatus() != 0) {
throw new RepositoryException(response.getErrorMessage());
}
RemoteIOObjectEntry entry = new RemoteIOObjectEntry(response, this, getRepository());
if (entries != null) {
entries.add(entry);
getRepository().fireEntryAdded(entry, this);
}
return entry;
}
@Override
public ProcessEntry createProcessEntry(String name, String processXML) throws RepositoryException {
RepositoryLocation loc;
try {
loc = new RepositoryLocation(getLocation(), name);
} catch (MalformedRepositoryLocationException e) {
throw new RepositoryException(e);
}
Response response = getRepository().getRepositoryService().storeProcess(loc.getPath(), processXML, null);
if (response.getStatus() != 0) {
throw new RepositoryException(response.getErrorMessage());
}
EntryResponse entryResponse = getRepository().getRepositoryService().getEntry(loc.getPath());
if (entryResponse.getStatus() != 0) {
throw new RepositoryException(entryResponse.getErrorMessage());
}
RemoteProcessEntry entry = new RemoteProcessEntry(entryResponse, this, getRepository());
if (entries != null) {
entries.add(entry);
}
getRepository().fireEntryAdded(entry, this);
return entry;
}
void removeChild(RemoteEntry remoteEntry) {
if (remoteEntry instanceof Folder) {
int index = folders.indexOf(remoteEntry);
folders.remove(remoteEntry);
getRepository().fireEntryRemoved(remoteEntry, this, index);
} else {
int index = entries.indexOf(remoteEntry) + folders.size();
entries.remove(remoteEntry);
getRepository().fireEntryRemoved(remoteEntry, this, index);
}
}
@Override
public boolean isReadOnly() {
return readOnly;
}
}