package com.jakeapp.gui.swing;
import com.jakeapp.availablelater.AvailableErrorObject;
import com.jakeapp.availablelater.AvailableLaterObject;
import com.jakeapp.core.dao.exceptions.NoSuchJakeObjectException;
import com.jakeapp.core.dao.exceptions.NoSuchProjectException;
import com.jakeapp.core.domain.*;
import com.jakeapp.core.domain.exceptions.FrontendNotLoggedInException;
import com.jakeapp.core.domain.exceptions.IllegalProtocolException;
import com.jakeapp.core.domain.exceptions.InvalidCredentialsException;
import com.jakeapp.core.domain.exceptions.NoSuchMsgServiceException;
import com.jakeapp.core.domain.exceptions.UserFormatException;
import com.jakeapp.core.domain.logentries.LogEntry;
import com.jakeapp.core.services.IFrontendService;
import com.jakeapp.core.services.IProjectsManagingService;
import com.jakeapp.core.services.MsgService;
import com.jakeapp.core.services.exceptions.ProtocolNotSupportedException;
import com.jakeapp.core.services.futures.AnnounceFuture;
import com.jakeapp.core.services.futures.ImportFilesFuture;
import com.jakeapp.core.services.futures.ProjectNoteCountFuture;
import com.jakeapp.core.services.futures.PullFuture;
import com.jakeapp.core.services.futures.StartStopProjectFuture;
import com.jakeapp.core.synchronization.IFriendlySyncService;
import com.jakeapp.core.synchronization.UserInfo;
import com.jakeapp.core.synchronization.attributes.Attributed;
import com.jakeapp.gui.swing.actions.project.StartStopProjectAction;
import com.jakeapp.gui.swing.callbacks.FilesChangedCallback;
import com.jakeapp.gui.swing.callbacks.ProjectChangedCallback;
import com.jakeapp.gui.swing.exceptions.FileOperationFailedException;
import com.jakeapp.gui.swing.exceptions.InvalidNewFolderException;
import com.jakeapp.gui.swing.exceptions.NoteOperationFailedException;
import com.jakeapp.gui.swing.exceptions.PeopleOperationFailedException;
import com.jakeapp.gui.swing.exceptions.ProjectCreationException;
import com.jakeapp.gui.swing.exceptions.ProjectNotFoundException;
import com.jakeapp.gui.swing.globals.JakeContext;
import com.jakeapp.gui.swing.helpers.ExceptionUtilities;
import com.jakeapp.gui.swing.helpers.FileUtilities;
import com.jakeapp.gui.swing.helpers.FolderObject;
import com.jakeapp.gui.swing.xcore.EventCore;
import com.jakeapp.gui.swing.xcore.JakeObjectAttributedCacheManager;
import com.jakeapp.jake.fss.IFileModificationListener;
import com.jakeapp.jake.fss.IModificationListener.ModifyActions;
import com.jakeapp.jake.fss.exceptions.CreatingSubDirectoriesFailedException;
import com.jakeapp.jake.fss.exceptions.FileAlreadyExistsException;
import com.jakeapp.jake.fss.exceptions.InvalidFilenameException;
import com.jakeapp.jake.fss.exceptions.LaunchException;
import com.jakeapp.jake.fss.exceptions.NotADirectoryException;
import com.jakeapp.jake.fss.exceptions.NotAFileException;
import com.jakeapp.jake.fss.exceptions.NotAReadableFileException;
import com.jakeapp.jake.ics.exceptions.NetworkException;
import com.jakeapp.jake.ics.status.ILoginStateListener;
import org.apache.log4j.Logger;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
public class SpringCoreAccessImpl implements ICoreAccess {
private static final Logger log = Logger.getLogger(SpringCoreAccessImpl.class);
private IFrontendService frontendService;
private IProjectsManagingService pms;
private IFriendlySyncService iss;
private final JakeObjectAttributedCacheManager attributedCacheMan =
new JakeObjectAttributedCacheManager();
/**
* SessionId returned by the authentication Method of
* FrontendService.authenticate.
*/
private String sessionId;
private Map<FilesChangedCallback, IFileModificationListener> fileListeners =
new HashMap<FilesChangedCallback, IFileModificationListener>();
private IFrontendService getFrontendService() {
return this.frontendService;
}
private String getSessionId() {
return this.sessionId;
}
@Override
public AvailableLaterObject<List<Project>> getProjects() {
return pms.getProjects(JakeContext.getMsgService());
}
@Override
public List<Invitation> getInvitations() {
if (JakeContext.getMsgService() != null) {
return this.pms.getInvitations(JakeContext.getMsgService());
} else {
return new ArrayList<Invitation>();
}
}
@Override
public void setFrontendService(IFrontendService frontendService) {
this.frontendService = frontendService;
}
private void handleNotLoggedInException(FrontendNotLoggedInException e) {
ExceptionUtilities.showError("Tried access core without a session", e);
}
@Override
public void authenticateOnBackend(Map<String, String> authenticationData)
throws InvalidCredentialsException {
this.sessionId = this.frontendService
.authenticate(authenticationData, EventCore.get().getChangeListener());
// also cache the pms
pms = frontendService.getProjectsManagingService(this.sessionId);
iss = getFrontendService().getSyncService(getSessionId());
// set the invitation listener
// pms.setInvitationListener(EventCore.get().getInvitationListener());
}
@Override
public void backendLogOff() {
log.info("Logging out of the backend...");
try {
this.frontendService.logout(this.sessionId);
} catch (FrontendNotLoggedInException e) {
log.warn("Frontent not logged in", e);
}
this.sessionId = "";
}
@Override
public List<MsgService<User>> getMsgServices()
throws FrontendNotLoggedInException {
return this.frontendService.getMsgServices(this.sessionId);
}
@Override
public AvailableLaterObject<Void> createAccount(Account credentials)
throws FrontendNotLoggedInException, InvalidCredentialsException,
ProtocolNotSupportedException, NetworkException {
return this.frontendService.createAccount(this.sessionId, credentials);
}
@Override
public MsgService addAccount(Account credentials)
throws FrontendNotLoggedInException, InvalidCredentialsException,
ProtocolNotSupportedException, NetworkException {
return this.frontendService.addAccount(this.sessionId, credentials);
}
@Override
public void removeAccount(MsgService msg)
throws FrontendNotLoggedInException, InvalidCredentialsException,
ProtocolNotSupportedException, NetworkException,
NoSuchMsgServiceException {
this.frontendService.removeAccount(this.sessionId, msg);
}
// only start from StartStopProjectTask
public AvailableLaterObject<Void> startStopProject(Project project,
boolean start) {
log.info("Starting project: " + project);
return new StartStopProjectFuture(pms, project, start).start();
}
public AvailableLaterObject<Integer> getProjectFileCount(Project project) {
AvailableLaterObject<Integer> result = null;
Exception ex = null;
try {
result = this.getFrontendService()
.getProjectsManagingService(this.getSessionId())
.getProjectFileCount(project);
} catch (FileNotFoundException e) {
ex = e;
} catch (IllegalArgumentException e) {
ex = e;
} catch (IllegalStateException e) {
ex = e;
} catch (NoSuchProjectException e) {
ex = e;
} catch (FrontendNotLoggedInException e) {
this.handleNotLoggedInException(e);
ex = e;
}
if (result == null)
result = new AvailableErrorObject<Integer>(ex).start();
return result;
}
public AvailableLaterObject<Long> getProjectSizeTotal(Project project) {
AvailableLaterObject<Long> result = null;
Exception ex = null;
try {
result = this.getFrontendService()
.getProjectsManagingService(this.getSessionId())
.getProjectSizeTotal(project);
} catch (FrontendNotLoggedInException e) {
this.handleNotLoggedInException(e);
ex = e;
} catch (Exception e) {
ex = e;
}
if (result == null)
result = new AvailableErrorObject<Long>(ex).start();
return result.start();
}
public void deleteProject(final Project project,
final boolean deleteProjectFiles) {
log.info(
"Delete project: " + project + " deleteProjectFiles: " + deleteProjectFiles);
if (project == null) {
throw new IllegalArgumentException("Cannot delete empty project!");
}
// FIXME: convert to availablelater?
Runnable runner = new Runnable() {
public void run() {
boolean ret;
try {
// search project in list
ret = getFrontendService().getProjectsManagingService(getSessionId())
.deleteProject(project, deleteProjectFiles);
if (!ret) {
throw new ProjectNotFoundException("Project not found in list!");
}
EventCore.get().fireProjectChanged(
new ProjectChangedCallback.ProjectChangedEvent(project,
ProjectChangedCallback.ProjectChangedEvent.Reason.Deleted));
} catch (FrontendNotLoggedInException e) {
handleNotLoggedInException(e);
} catch (RuntimeException run) {
ExceptionUtilities.showError(run);
} catch (IOException e) {
//report to gui that the rootpath is invalid
ExceptionUtilities.showError("Project cannot be deleted:", e);
} catch (NotADirectoryException e) {
//report to gui that the rootpath is invalid
ExceptionUtilities
.showError("Project cannot be deleted: its folder does not exist.",
e);
} catch (NoSuchProjectException e) {
ExceptionUtilities.showError(e);
}
}
};
// start our runner thread, that makes a callback to project status
new Thread(runner).start();
}
public void joinProject(final String path, final Invitation invitation) {
if (path == null)
throw new IllegalArgumentException("Path may not be null");
if (invitation == null)
throw new IllegalArgumentException("Invitation may not be null");
// check if we need to create the path!
boolean success = false;
try {
success = FileUtilities.createDirectory(path);
} catch (Exception ex) {
ExceptionUtilities.showError("Couldn't create the path " + path, ex);
}
// premature quit if folder couldn't be created
if (!success) {
log.warn("Stopped join project because folder couldn't be created.");
return;
}
log.info("Joining project " + invitation
.getProjectName() + " with path: " + path);
Runnable runner = new Runnable() {
public void run() {
try {
pms.acceptInvitation(invitation, new File(path));
Project project = invitation.createProject();
EventCore.get().fireProjectChanged(
new ProjectChangedCallback.ProjectChangedEvent(project,
ProjectChangedCallback.ProjectChangedEvent.Reason.Joined));
// start the project!
StartStopProjectAction.perform(project);
} catch (FrontendNotLoggedInException e) {
handleNotLoggedInException(e);
} catch (RuntimeException run) {
ExceptionUtilities.showError(run);
} catch (NoSuchProjectException e) {
ExceptionUtilities.showError(e);
}
}
};
// start our runner thread, that makes a callback to project status
new Thread(runner).start();
}
public void rejectInvitation() {
final Invitation invitation = JakeContext.getInvitation();
log.info("Reject invitation: " + invitation);
Runnable runner = new Runnable() {
public void run() {
try {
getFrontendService().getProjectsManagingService(getSessionId())
.rejectInvitation(invitation);
// FIXME: One fine day, far far far away, make this prettier.
EventCore.get().fireProjectChanged(
new ProjectChangedCallback.ProjectChangedEvent(null,
ProjectChangedCallback.ProjectChangedEvent.Reason.Rejected));
} catch (FrontendNotLoggedInException e) {
ExceptionUtilities.showError(e);
} catch (RuntimeException e) {
ExceptionUtilities.showError(e);
} catch (NoSuchProjectException e) {
ExceptionUtilities.showError(e);
}
}
};
// start our runner thread, that makes a callback to project status
new Thread(runner).start();
}
@Override
// TODO: should be a running later ?
public void syncProject(Project project, User user) {
log.debug("syncin' project " + project.getName() + " with user " + user);
try {
if (user != null) {
iss.poke(project, user);
iss.startLogSync(project, user);
} else {
iss.poke(project);
iss.startLogSync(project);
}
EventCore.get().fireProjectChanged(
new ProjectChangedCallback.ProjectChangedEvent(project,
ProjectChangedCallback.ProjectChangedEvent.Reason.Syncing));
} catch (IllegalArgumentException e) {
ExceptionUtilities.showError(e);
} catch (IllegalStateException e) {
ExceptionUtilities.showError(e);
} catch (FrontendNotLoggedInException e) {
this.handleNotLoggedInException(e);
} catch (NoSuchProjectException e) {
ExceptionUtilities.showError(e);
} catch (IllegalProtocolException e) {
e.printStackTrace();
}
}
public void setProjectName(Project project, String prName) {
try {
this.getFrontendService().getProjectsManagingService(this.getSessionId())
.updateProjectName(project, prName);
EventCore.get().fireProjectChanged(
new ProjectChangedCallback.ProjectChangedEvent(project,
ProjectChangedCallback.ProjectChangedEvent.Reason.Name));
} catch (IllegalArgumentException e) {
//empty implementation
} catch (IllegalStateException e) {
//empty implementation
} catch (NoSuchProjectException e) {
//empty implementation
} catch (FrontendNotLoggedInException e) {
this.handleNotLoggedInException(e);
}
}
@Override
public AvailableLaterObject<Collection<FileObject>> getFiles(Project project) {
log.debug("Calling getFiles");
AvailableLaterObject<Collection<FileObject>> result = null;
Exception ex = null;
try {
result = this.frontendService.getProjectsManagingService(this.sessionId)
.getAllProjectFiles(project);
} catch (IOException e) {
ex = new FileOperationFailedException(e);
} catch (IllegalArgumentException e) {
ex = e;
} catch (FrontendNotLoggedInException e) {
ex = e;
} catch (IllegalStateException e) {
ex = e;
} catch (NoSuchProjectException e) {
ex = e;
}
if (result == null) {
log.debug("getFiles failed, returning error", ex);
result = new AvailableErrorObject<Collection<FileObject>>(ex);
}
log.debug("getFiles - start AvailableLaterObject");
return result;
}
@Override
public <T extends JakeObject> Attributed<T> getAttributed(T jakeObject) {
Attributed<T> result = null;
try {
// sanity check - hey, we don't wanna mess with the core!
if (jakeObject == null) {
return null;
}
// first, look if we have a recent revision in the cache
// FIXME: the cache does not respect the attributes of a jake object. If somehow only the
// attributes are changed (e.g. commit note) but note the jake object itself, the cache
// returnes the outdated attributes!!!
// TODO fix the bug described above by calling {@link AttributedCacheManager#invalidateCache}
// for every JakeObject that changes
result = attributedCacheMan.getCached(jakeObject);
if (result == null) {
Attributed<T> syncStatus = this.iss.getJakeObjectSyncStatus(jakeObject);
result = attributedCacheMan.cacheObject(jakeObject, syncStatus);
}
} catch (NotAFileException e) {
ExceptionUtilities.showError(e);
} catch (FileNotFoundException e) {
ExceptionUtilities.showError(e);
} catch (InvalidFilenameException e) {
ExceptionUtilities.showError(e);
} catch (NotAReadableFileException e) {
ExceptionUtilities.showError(e);
} catch (FrontendNotLoggedInException e) {
this.handleNotLoggedInException(e);
} catch (IOException e) {
ExceptionUtilities.showError(e);
} catch (Exception e) {
ExceptionUtilities
.showError("Catched generic exception while getting sync status", e);
}
return result;
}
public AvailableLaterObject<Collection<NoteObject>> getNotes(
final Project project) {
log.debug("starting");
AvailableLaterObject<Collection<NoteObject>> result = null;
Exception ex = null;
try {
result = this.frontendService.getProjectsManagingService(this.sessionId)
.getAllProjectNotes(project);
} catch (IllegalArgumentException e) {
ex = e;
} catch (FrontendNotLoggedInException e) {
ex = e;
} catch (IllegalStateException e) {
ex = e;
} catch (NoSuchProjectException e) {
ex = e;
}
if (result == null) {
log.debug("failed, returning error", ex);
result = new AvailableErrorObject<Collection<NoteObject>>(ex);
}
log.debug("start AvailableLaterObject");
return result;
}
@Override
public AvailableLaterObject<Integer> getNoteCount(final Project project) {
return new ProjectNoteCountFuture(this.getNotes(project));
}
@Override public void setProjectSettings(Project p, Boolean autoPull,
Boolean autoPush) {
if (autoPull != null)
p.setAutoPullEnabled(autoPull);
if (autoPush != null)
p.setAutoAnnounceEnabled(autoPush);
// FIXME: needs support from core?
// where do we activate the code that activates the watcher?
}
@Override
public void createNote(NoteObject note) throws NoteOperationFailedException {
try {
pms.saveNote(note);
} catch (Exception e) {
throw new NoteOperationFailedException(e);
}
EventCore.get().fireNotesChanged(note.getProject());
}
@Override
public AvailableLaterObject<Void> deleteNote(final NoteObject note) {
return new AvailableLaterObject<Void>() {
@Override
public Void calculate() throws Exception {
pms.deleteNote(note);
return null;
}
};
}
@Override
public AvailableLaterObject<Integer> deleteNotes(final List<NoteObject> notes) {
for (NoteObject no : notes)
this.attributedCacheMan.invalidateCache(no);
return new AvailableLaterObject<Integer>() {
@Override
public Integer calculate() throws Exception {
for (NoteObject note : notes)
pms.deleteNote(note);
return notes.size();
}
};
}
@Override
public void saveNote(NoteObject note) throws NoteOperationFailedException {
pms.saveNote(note);
this.attributedCacheMan.invalidateCache(note);
EventCore.get().fireNotesChanged(note.getProject());
}
/**
* Generates a list so that people are remembered when they change.
*
* @param project : project that should be evaluated
* @return list of people in this project OR empty list.
*/
public List<UserInfo> getAllProjectMembers(Project project)
throws PeopleOperationFailedException {
log.info("getUser from project " + project);
List<UserInfo> users = new ArrayList<UserInfo>();
if (project == null) {
log.warn("Get People for empty project.");
return users;
}
try {
return pms.getProjectUserInfos(project);
} catch (NoSuchProjectException ex) {
throw new PeopleOperationFailedException(ex);
}
}
@Override
public UserInfo getUserInfo(User user) {
if (user == null)
return null;
try {
return pms.getProjectUserInfo(JakeContext.getProject(), user);
} catch (Exception ex) {
log.warn("Error catching UserInfo", ex);
return null;
}
}
@Override
public boolean setUserNick(Project project, User user, String nick) {
log.debug(
"setUserNick: project: " + project + " ProjectMember: " + user + " Nick: " + nick);
// FIXME: AS OF 1.3.09, this seems broken?
// TODO: ignore this and create a regex for checking!
if (nick.indexOf("<") != -1) {
return false;
} else {
pms.setUserNickname(project, user, nick);
EventCore.get().fireProjectChanged(
new ProjectChangedCallback.ProjectChangedEvent(project,
ProjectChangedCallback.ProjectChangedEvent.Reason.People));
return true;
}
}
@Override
public void setTrustState(Project project, User user, TrustState trust) {
try {
pms.setTrust(project, user, trust);
} catch (IllegalArgumentException e) {
ExceptionUtilities.showError(e);
} catch (IllegalAccessException e) {
ExceptionUtilities.showError(e);
}
EventCore.get().fireProjectChanged(
new ProjectChangedCallback.ProjectChangedEvent(project,
ProjectChangedCallback.ProjectChangedEvent.Reason.People));
}
@Override
public void inviteUser(Project project, String userid) {
try {
this.getFrontendService().getProjectsManagingService(getSessionId())
.invite(project, userid);
EventCore.get().fireProjectChanged(
new ProjectChangedCallback.ProjectChangedEvent(project,
ProjectChangedCallback.ProjectChangedEvent.Reason.People));
} catch (IllegalArgumentException e) {
ExceptionUtilities.showError(e);
} catch (FrontendNotLoggedInException e) {
this.handleNotLoggedInException(e);
} catch (IllegalStateException e) {
ExceptionUtilities.showError(e);
} catch (UserFormatException e) {
ExceptionUtilities.showError(e);
} catch (Exception e) {
ExceptionUtilities.showError(e);
}
}
@Override
public List<User> getSuggestedUser(Project project) {
List<User> members = null;
try {
members = this.getFrontendService().getProjectsManagingService(getSessionId())
.getSuggestedPeopleForInvite(project);
} catch (IllegalArgumentException e) {
ExceptionUtilities.showError(e);
} catch (FrontendNotLoggedInException e) {
this.handleNotLoggedInException(e);
} catch (IllegalStateException e) {
ExceptionUtilities.showError(e);
} catch (NoSuchProjectException e) {
ExceptionUtilities.showError(e);
}
//never return null
return (members == null) ? new ArrayList<User>() : members;
}
@Override
public List<LogEntry<? extends ILogable>> getLog(Project project,
JakeObject jakeObject, int entries) {
log.trace(
"getLog pr:" + project + " jakeObject: " + jakeObject + " entries: " + entries);
List<LogEntry<? extends ILogable>> logs;
if (jakeObject == null) {
logs = pms.getLog(project);
} else {
logs = pms.getLog(jakeObject);
}
// filter log list?
if (entries != 0 && logs.size() > entries) {
return logs.subList(0, entries);
} else {
return logs;
}
}
@Override public Account getPredefinedServiceCredential(String s) {
log.debug("Fetch predefined Account for " + s);
// only support xmpp - for the moment
Account cred = new Account();
cred.setProtocol(ProtocolType.XMPP);
if (s.compareToIgnoreCase("google") == 0) {
log.debug("Returning special google credentials");
cred.setServerPort(5222);
cred.setServerAddress("talk.google.com");
} else if (s.compareToIgnoreCase("unitedinternet") == 0) {
// fixme: insert data!
}
return cred;
}
public void createProject(final String name, final String path,
final MsgService msg, final boolean startOnCreate)
throws ProjectCreationException {
log.debug("Create project: " + name + " path: " + path + " msg: " + msg);
// preconditions
if (path == null) {
throw new IllegalArgumentException("Path cannot be null.");
}
// TODO: AvailableLaterObject
Runnable runner = new Runnable() {
public void run() {
Project project;
try {
// add Project to core-internal list
project = pms.createProject(name, path, msg);
EventCore.get().fireProjectChanged(
new ProjectChangedCallback.ProjectChangedEvent(project,
ProjectChangedCallback.ProjectChangedEvent.Reason.Created));
if (startOnCreate) {
StartStopProjectAction.perform(project);
}
} catch (FrontendNotLoggedInException e) {
ExceptionUtilities.showError(
"Tried to create a project while not authenticated to the core.",
e);
} catch (RuntimeException e) {
ExceptionUtilities.showError(e);
} catch (Exception e) {
ExceptionUtilities.showError(e);
}
}
};
// start our runner thread, that makes a callback to project status
new Thread(runner).start();
}
@Override
public AvailableLaterObject<Void> importExternalFileFolderIntoProject(
Project project, List<File> files, String destFolderRelPath) {
return new ImportFilesFuture(this.pms.getFileServices(project), files,
destFolderRelPath).start();
}
@Override
public AvailableLaterObject<Void> deleteFile(FileObject fo, boolean trash) {
try {
return this.pms.deleteFile(fo, trash);
} catch (Exception e) {
return new AvailableErrorObject<Void>(e);
}
}
@Override
public AvailableLaterObject<Integer> deleteFiles(List<FileObject> fo,
boolean trash) {
return this.pms.deleteFiles(fo, trash);
}
@Override
public void rename(FileObject file, String newName) {
this.renamePath(file.getRelPath(), file.getProject(), newName);
//TODO change relpath - enable setRelPath
}
@Override
public void rename(FolderObject folder, String newName) {
this.renamePath(folder.getRelPath(), folder.getProject(), newName);
//TODO change relpath
}
@Override
public Set<Tag> getTagsForFileObject(FileObject fo) {
try {
return this.getFrontendService()
.getProjectsManagingService(this.getSessionId())
.getTagsForJakeObject(fo);
} catch (IllegalArgumentException e) {
ExceptionUtilities.showError(e);
} catch (FrontendNotLoggedInException e) {
this.handleNotLoggedInException(e);
} catch (IllegalStateException e) {
ExceptionUtilities.showError(e);
} catch (NoSuchJakeObjectException e) {
ExceptionUtilities.showError(e);
}
return new TreeSet<Tag>();
}
@Override
public void setTagsForFileObject(FileObject fo, Set<Tag> tags) {
try {
this.getFrontendService().getProjectsManagingService(this.getSessionId())
.setTagsForJakeObject(fo, tags);
} catch (IllegalArgumentException e) {
ExceptionUtilities.showError(e);
} catch (FrontendNotLoggedInException e) {
this.handleNotLoggedInException(e);
} catch (IllegalStateException e) {
ExceptionUtilities.showError(e);
} catch (NoSuchJakeObjectException e) {
ExceptionUtilities.showError(e);
}
}
/**
* Renames a file
*
* @param fromPath relative Path of source
* @param project Project to retrieve a FSService for - fromPath should be in the Project.
* @param newName new name
*/
private void renamePath(String fromPath, Project project, String newName) {
File toFile;
/*
* create a File with the same parent as the passed
* FROM-Path, but with a different name.
*/
toFile = new File(new File(fromPath).getParentFile(), newName);
try {
this.getFrontendService().
getProjectsManagingService(this.getSessionId()).
getFileServices(project).moveFile(fromPath, toFile.toString());
} catch (IllegalArgumentException e) {
ExceptionUtilities.showError("Cannot rename file", e);
} catch (IllegalStateException e) {
log.debug("Project service is not available.");
} catch (InvalidFilenameException e) {
ExceptionUtilities.showError("Filename of FileObject invalid: " + fromPath, e);
} catch (NotAReadableFileException e) {
ExceptionUtilities.showError("Cannot move an unreadable file", e);
} catch (FileAlreadyExistsException e) {
ExceptionUtilities
.showError("Cannot move file: destination already exists.", e);
} catch (IOException e) {
ExceptionUtilities.showError("Cannot rename file", e);
} catch (CreatingSubDirectoriesFailedException e) {
log.error("Creating a subdirectory that should not be created failed...");
} catch (FrontendNotLoggedInException e) {
this.handleNotLoggedInException(e);
}
}
@Override public AvailableLaterObject<Void> announceJakeObject(JakeObject jo,
String commitMsg) throws FileOperationFailedException {
return announceJakeObjects(Arrays.asList(jo), commitMsg);
}
@Override
public <T extends JakeObject> AvailableLaterObject<Void> announceJakeObjects(
List<T> jos, String commitMsg) throws FileOperationFailedException {
AvailableLaterObject<Void> result;
if (commitMsg == null)
commitMsg = "";
try {
result = new AnnounceFuture(iss, jos, commitMsg);
for (JakeObject jo : jos)
this.attributedCacheMan.invalidateCache(jo);
} catch (FrontendNotLoggedInException e) {
this.handleNotLoggedInException(e);
throw new FileOperationFailedException(e);
}
return result;
}
@Override
public AvailableLaterObject<Void> pullJakeObject(JakeObject jo)
throws FileOperationFailedException {
return this.pullJakeObjects(Arrays.asList(jo));
}
@Override
public AvailableLaterObject<Void> pullJakeObjects(List<JakeObject> jakeObjects)
throws FileOperationFailedException {
AvailableLaterObject<Void> result;
try {
result = new PullFuture(iss, jakeObjects);
} catch (FrontendNotLoggedInException e) {
this.handleNotLoggedInException(e);
throw new FileOperationFailedException(e);
}
return result.start();
}
@Override
public void createNewFolderAt(Project project, String relpath, String folderName)
throws InvalidNewFolderException {
try {
this.getFrontendService().getProjectsManagingService(getSessionId())
.getFileServices(project).createFolder(relpath);
} catch (IllegalArgumentException e) {
throw new InvalidNewFolderException(relpath);
} catch (FrontendNotLoggedInException e) {
this.handleNotLoggedInException(e);
} catch (IllegalStateException e) {
throw new InvalidNewFolderException(relpath);
} catch (InvalidFilenameException e) {
throw new InvalidNewFolderException(relpath);
} catch (IOException e) {
throw new InvalidNewFolderException(relpath);
}
}
@Override
public void addFilesChangedListener(final FilesChangedCallback listener,
Project project) {
IFileModificationListener fileModificationListener =
new IFileModificationListener() {
public void fileModified(String relpath, ModifyActions action) {
listener.filesChanged(relpath, action);
}
};
this.fileListeners.put(listener, fileModificationListener);
this.getFrontendService().getProjectsManagingService(getSessionId())
.getFileServices(project)
.addModificationListener(fileModificationListener);
}
@Override
public void removeFilesChangedListener(FilesChangedCallback listener,
Project project) {
IFileModificationListener fileModificationListener;
fileModificationListener = this.fileListeners.get(listener);
if (fileModificationListener != null)
this.getFrontendService().getProjectsManagingService(getSessionId())
.getFileServices(project)
.removeModificationListener(fileModificationListener);
}
@Override
public long getLocalFileSize(FileObject fo) {
try {
//since the method only checks local files, it fails for files
//that only exist remotely
return this.getFrontendService().getProjectsManagingService(getSessionId())
.getFileServices(fo.getProject()).getFileSize(fo.getRelPath());
} catch (FileNotFoundException e) {
ExceptionUtilities.showError(e);
} catch (NotAFileException e) {
ExceptionUtilities.showError(e);
} catch (IllegalArgumentException e) {
ExceptionUtilities.showError(e);
} catch (FrontendNotLoggedInException e) {
this.handleNotLoggedInException(e);
} catch (IllegalStateException e) {
ExceptionUtilities.showError(e);
} catch (InvalidFilenameException e) {
ExceptionUtilities.showError(e);
}
return 0;
}
@Override
public Date getLocalFileLastModified(FileObject fo) {
try {
//since the method only checks local files, it fails for files
//that only exist remotely
return new Date(
this.getFrontendService().getProjectsManagingService(getSessionId())
.getFileServices(fo.getProject()).getLastModified(
fo.getRelPath()));
} catch (NotAFileException e) {
ExceptionUtilities.showError(e);
} catch (IllegalArgumentException e) {
ExceptionUtilities.showError(e);
} catch (FrontendNotLoggedInException e) {
this.handleNotLoggedInException(e);
} catch (IllegalStateException e) {
ExceptionUtilities.showError(e);
} catch (InvalidFilenameException e) {
ExceptionUtilities.showError(e);
}
return new Date();
}
@Override
public void setSoftLock(JakeObject jakeObject, boolean isSet,
String lockingMessage) {
if (isSet) {
this.getFrontendService().getProjectsManagingService(getSessionId())
.lock(jakeObject, lockingMessage);
} else {
this.getFrontendService().getProjectsManagingService(getSessionId())
.unlock(jakeObject, lockingMessage);
}
EventCore.get().fireProjectChanged(
new ProjectChangedCallback.ProjectChangedEvent(jakeObject.getProject(),
ProjectChangedCallback.ProjectChangedEvent.Reason.Deleted));
}
@Override
public AvailableLaterObject<Boolean> login(MsgService service, Account credentials,
ILoginStateListener connectionListener) {
////fixme unregister
service.registerInvitationListener(
EventCore.get().getInvitationListener()); // TODO DIRTY!
return this.getFrontendService()
.login(getSessionId(), service, credentials, connectionListener);
}
@Override
public File getFile(FileObject fo) throws FileOperationFailedException {
//log.debug("getFile: fo: " + fo + " in pr: " + (fo != null ? fo.getProject() :
// null));
// no need to go in iss if everything is null.
if (fo == null) {
log.warn("Tried to get a File with FileObject Null");
return null;
}
IFriendlySyncService sync = this.frontendService.getSyncService(this.sessionId);
try {
return sync.getFile(fo);
} catch (Exception e) {
throw new FileOperationFailedException(e);
}
}
@Override
public void registerFileWatcher(Project project,
IFileModificationListener listener) {
this.pms.getFileServices(project).removeModificationListener(listener);
this.pms.getFileServices(project).addModificationListener(listener);
}
@Override
public void launch(FileObject fo)
throws IllegalArgumentException, InvalidFilenameException, LaunchException,
IOException {
this.pms.getFileServices(fo.getProject()).launchFile(fo.getRelPath());
}
}