Project: eclipse-task-editor
/*******************************************************************************
 * Copyright (c) 2011 Sebastian Benz. 
 * 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: 
 *     Sebastian Benz - initial API and implementation 
 ******************************************************************************/
package de.sebastianbenz.task.ui.editor; 
 
import org.eclipse.core.resources.IFile; 
import org.eclipse.core.resources.IFolder; 
import org.eclipse.core.resources.IProject; 
import org.eclipse.core.resources.IResource; 
import org.eclipse.core.resources.IWorkspace; 
import org.eclipse.core.resources.ResourcesPlugin; 
import org.eclipse.core.runtime.CoreException; 
import org.eclipse.core.runtime.IPath; 
import org.eclipse.core.runtime.NullProgressMonitor; 
import org.eclipse.core.runtime.Path; 
import org.eclipse.emf.common.util.WrappedException; 
import org.eclipse.ui.IFileEditorInput; 
import org.eclipse.ui.PlatformUI; 
import org.eclipse.xtext.builder.nature.ToggleXtextNatureAction; 
 
import com.google.inject.Inject; 
 
@SuppressWarnings("restriction"
public class ExtLinkedFileHelper { 
 // TODO: Should be configurable 
 public static final String AUTOLINK_PROJECT_NAME = ".todoProject"
 
 public static final String ENCODING_UTF8 = "utf-8"
  
 @Inject 
 private ToggleXtextNatureAction toggleNature; 
  
 /**
  * Throws WrappedException - the URI must refer to an existing file! 
  *  
  * @param uri 
  * @return 
  */
 
 public IFile obtainLink(java.net.URI uri, boolean untitled) { 
  try { 
   IWorkspace ws = ResourcesPlugin.getWorkspace(); 
   // get, or create project if non existing 
   IProject project = ws.getRoot().getProject(AUTOLINK_PROJECT_NAME); 
   boolean newProject = false
   if(!project.exists()) { 
    project.create(null); 
     
    newProject = true
   
   if(!project.isOpen()) { 
    project.open(null); 
    // if project is hidden files can not be opened in all cases 
    // TODO: Add reference to Xtext issue. 
    project.setHidden(false); 
   
    
   if(!toggleNature.hasNature(project)){ 
    toggleNature.toggleNature(project); 
   
 
   if(newProject) 
    project.setDefaultCharset(ENCODING_UTF8, new NullProgressMonitor()); 
   IFile linkFile = null
   if(untitled) { 
    int firstFree = getFirstFreeUntitled(project); 
    IFolder untitledFolder = project.getFolder("untitled"); 
    String fileName = "untitled" + (firstFree > 1 
      "-" + Integer.toString(firstFree) 
      "") + ".todo"
    linkFile = untitledFolder.getFile(fileName); 
   
   else { 
    // path in project that is the same as the external file's path to avoid collision 
    // without need to create new names 
    linkFile = project.getFile(uri.getPath()); 
   
   if(linkFile.exists()) 
    linkFile.refreshLocal(1null); // don't know if needed (or should be avoided...) 
   else { 
    // create the link 
    createLink(project, linkFile, uri); 
   
   return linkFile; 
  
  catch(CoreException e) { 
   throw new WrappedException(e); 
  
 
 
 public void unlinkInput(IFileEditorInput input) { 
  IFile file = input.getFile(); 
  // only delete links if they are in the autolink project 
  if(file.isLinked() && file.getProject().getName().equals(ExtLinkedFileHelper.AUTOLINK_PROJECT_NAME)) { 
   try { 
    // if the editor is disposed because workbench is shutting down, it is NOT a good 
    // idea to delete the link 
    if(PlatformUI.isWorkbenchRunning() && !PlatformUI.getWorkbench().isClosing()) 
     file.delete(truenull); 
   
   catch(CoreException e) { 
    // Nothing to do really, it will be recreated/refreshed later if ever used - some garbage may stay behind... 
    // TODO: log the issue 
    e.printStackTrace(); 
   
  
 
 
 private void createLink(IProject project, IFile linkFile, java.net.URI uri) throws CoreException { 
  IPath path = linkFile.getFullPath(); 
 
  IPath folders = path.removeLastSegments(1).removeFirstSegments(1); 
  IPath checkPath = Path.ROOT; 
  int segmentCount = folders.segmentCount(); 
  for(int i = 0; i < segmentCount; i++) { 
   checkPath = checkPath.addTrailingSeparator().append(folders.segment(i)); 
   IFolder folder = project.getFolder(checkPath); 
   if(!folder.exists()) 
    folder.create(truetruenull); 
  
  linkFile.createLink(uri, IResource.ALLOW_MISSING_LOCAL, null); 
 
 
 private int getFirstFreeUntitled(IProject project) throws CoreException { 
  IFolder untitledFolder = project.getFolder("untitled"); 
  if(!untitledFolder.exists()) { 
   untitledFolder.create(truetruenew NullProgressMonitor()); 
   return 0
  
  IResource[] resources = untitledFolder.members(); 
  int result = resources.length > 0 
    1 
    0
  for(IResource r : resources) { 
   // tied to format "untitled-n" 
   int dash = r.getName().indexOf("-"); 
   if(dash < 0
    continue
   String substring = r.getName().substring(dash + 1, r.getName().length() - 5); 
   int sequence = Integer.valueOf(substring); 
   result = sequence > result 
     ? sequence 
     : result; 
  
  return result + 1
 
}