1 package net.sourceforge.phpeclipse.wiki.actions;
 
   3 import java.io.ByteArrayInputStream;
 
   5 import net.sourceforge.phpeclipse.wiki.editor.WikiEditor;
 
   6 import net.sourceforge.phpeclipse.wiki.editor.WikiEditorPlugin;
 
   7 import net.sourceforge.phpeclipse.wiki.preferences.Util;
 
   8 import net.sourceforge.phpeclipse.wiki.xml.Page;
 
   9 import net.sourceforge.phpeclipse.wiki.xml.XStreamManager;
 
  11 import org.eclipse.core.resources.IContainer;
 
  12 import org.eclipse.core.resources.IFile;
 
  13 import org.eclipse.core.resources.IFolder;
 
  14 import org.eclipse.core.resources.IProject;
 
  15 import org.eclipse.core.resources.IResource;
 
  16 import org.eclipse.core.resources.IResourceStatus;
 
  17 import org.eclipse.core.resources.ResourcesPlugin;
 
  18 import org.eclipse.core.runtime.CoreException;
 
  19 import org.eclipse.core.runtime.IPath;
 
  20 import org.eclipse.core.runtime.IProgressMonitor;
 
  21 import org.eclipse.core.runtime.Path;
 
  22 import org.eclipse.core.runtime.SubProgressMonitor;
 
  23 import org.eclipse.jface.action.IAction;
 
  24 import org.eclipse.jface.text.BadLocationException;
 
  25 import org.eclipse.jface.text.IDocument;
 
  26 import org.eclipse.jface.text.ITextSelection;
 
  27 import org.eclipse.jface.text.TextSelection;
 
  28 import org.eclipse.jface.viewers.ISelection;
 
  29 import org.eclipse.ui.IEditorActionDelegate;
 
  30 import org.eclipse.ui.IEditorPart;
 
  31 import org.eclipse.ui.IFileEditorInput;
 
  32 import org.eclipse.ui.IWorkbenchWindow;
 
  33 import org.eclipse.ui.ide.IDE;
 
  34 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
 
  35 import org.eclipse.ui.texteditor.AbstractTextEditor;
 
  37 public class OpenWikiLinkEditorAction implements IEditorActionDelegate {
 
  39   protected IWorkbenchWindow window;
 
  41   protected AbstractTextEditor editor;
 
  43   public void dispose() {
 
  46   public void init(IWorkbenchWindow window) {
 
  50   public void selectionChanged(IAction action, ISelection selection) {
 
  51     if (selection.isEmpty()) {
 
  54     if (selection instanceof TextSelection) {
 
  55       action.setEnabled(true);
 
  58     if (window.getActivePage() != null && window.getActivePage().getActivePart() != null) {
 
  59       action.setEnabled(window.getActivePage().getActivePart().getClass().equals(WikiEditor.class));
 
  63   public void run(IAction action) {
 
  65       IEditorPart targetEditor = window.getActivePage().getActiveEditor();
 
  66       if (targetEditor != null && (targetEditor instanceof AbstractTextEditor)) {
 
  67         editor = (AbstractTextEditor) targetEditor;
 
  71       openWikiLinkOnSelection();
 
  75   public void setActiveEditor(IAction action, IEditorPart targetEditor) {
 
  76     if (targetEditor != null && (targetEditor instanceof AbstractTextEditor)) {
 
  77       editor = (AbstractTextEditor) targetEditor;
 
  81   public static String getWikiTitle(AbstractTextEditor editor, IDocument document, int initialPos) {
 
  84       int line = document.getLineOfOffset(pos);
 
  85       int start = document.getLineOffset(line);
 
  86       int end = start + document.getLineInformation(line).getLength();
 
  89        * The line does not include \n or \r so pos can be > end. Making pos = end in this case is safe for the purposes of
 
  90        * determining the TextRegion at the cursor position
 
  96       int offsetInLine = pos - start;
 
  97       String word = document.get(start, end - start);
 
  98       int wordlen = word.length();
 
  99       int wikiLinkStart = -1;
 
 100       int wikiLinkEnd = -1;
 
 102       for (int i = offsetInLine; i < wordlen; i++) {
 
 103         if (word.charAt(i) == ']' && i < wordlen - 1 && word.charAt(i + 1) == ']') {
 
 107         if (word.charAt(i) == '|') {
 
 111         if (word.charAt(i) == '#') {
 
 116       for (int i = offsetInLine; i >= 0; i--) {
 
 117         if (word.charAt(i) == '[' && i > 0 && word.charAt(i - 1) == '[') {
 
 118           wikiLinkStart = i + 1;
 
 121         if (word.charAt(i) == '|') { // links with different description
 
 124         if (word.charAt(i) == '#') { // for links with anchors
 
 128       if (wikiLinkStart != (-1) && wikiLinkEnd != (-1) && wikiLinkStart < wikiLinkEnd) {
 
 129         return new String(word.toCharArray(), wikiLinkStart, wikiLinkEnd - wikiLinkStart);
 
 131     } catch (BadLocationException e) {
 
 137   public IDocument getDocument() {
 
 138     IDocument doc = editor.getDocumentProvider().getDocument(editor.getEditorInput());
 
 142   public void openWikiLinkOnSelection() {
 
 143     IDocument doc = getDocument();
 
 144     ITextSelection selection = (ITextSelection) editor.getSelectionProvider().getSelection();
 
 145     int pos = selection.getOffset();
 
 147     String wikiTitle = getWikiTitle(editor, doc, pos);
 
 148     IFileEditorInput ei = (IFileEditorInput) editor.getEditorInput();
 
 149     openWikiFile(ei.getFile(), wikiTitle, true);
 
 152   //  public void openWikiUrl(IProject project, String wikiTitle) {
 
 153   //    if (wikiTitle != null && !wikiTitle.equals("")) {
 
 154   //      IFile cfile = project.getFile("dummy.wp");
 
 155   //      IFile file = getWikiFile(cfile, wikiTitle);
 
 157   //        createNewFileIfNeeded(file, wikiTitle);
 
 159   //        IDE.openEditor(WikiEditorPlugin.getDefault().getActivePage(), file, true);
 
 160   //      } catch (Exception e) {
 
 162   // WikiEditorPlugin.getDefault().logAndReport(WikiEditorPlugin.getResourceString(WikiConstants.RESOURCE_WIKI_ERROR_DIALOGUE_OPEN_WIKI_FILE_TITLE),
 
 163   //        // WikiPlugin.getResourceString(WikiConstants.RESOURCE_WIKI_ERROR_DIALOGUE_OPEN_WIKI_FILE_TEXT), e);
 
 168   protected void openWikiFile(IFile cfile, String wikiTitle, boolean openEditor) {
 
 169     if (wikiTitle != null && !wikiTitle.equals("")) {
 
 170       IFile file = getWikiFile(cfile, wikiTitle);
 
 172         createNewFileIfNeeded(file, wikiTitle);
 
 174         Page page = new Page("", wikiTitle, "");
 
 175         page.createXMLFile(file, false);
 
 176 //        createXMLFile(wikiTitle, file, false);
 
 178         IDE.openEditor(WikiEditorPlugin.getDefault().getActivePage(), file, true);
 
 179       } catch (Exception e) {
 
 180         //                        WikiEditorPlugin.getDefault().logAndReport(WikiEditorPlugin.getResourceString(WikiConstants.RESOURCE_WIKI_ERROR_DIALOGUE_OPEN_WIKI_FILE_TITLE),
 
 181         // WikiPlugin.getResourceString(WikiConstants.RESOURCE_WIKI_ERROR_DIALOGUE_OPEN_WIKI_FILE_TEXT), e);
 
 189    * @throws CoreException
 
 191   private void createXMLFile(String wikiTitle, IFile file, boolean modify) throws CoreException {
 
 192     String srcBasePath = Util.getWikiTextsPath(file);
 
 193     String binBasePath = Util.getProjectsWikiOutputPath(file.getProject(), WikiEditorPlugin.HTML_OUTPUT_PATH);
 
 195     String filename = Util.getXMLFileName(file, binBasePath, srcBasePath);
 
 196     IPath path = new Path(filename);
 
 197     IFile xmlFile = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
 
 198     IContainer parent = xmlFile.getParent();
 
 199     if (parent instanceof IFolder && (!((IFolder) parent).exists())) {
 
 200       Util.createFolder((IFolder) parent, null);
 
 202     Page page = new Page("", wikiTitle, "");
 
 203     byte[] buffer = XStreamManager.toXML(page).getBytes();
 
 204     ByteArrayInputStream source = new ByteArrayInputStream(buffer);
 
 205     if (!xmlFile.exists()) {
 
 206       // only if file doesn't exists
 
 207       xmlFile.create(source, true, null);
 
 210         xmlFile.setContents(source, true, true, null);
 
 215   protected void createNewFileIfNeeded(IFile file, String word) throws CoreException {
 
 216     if (!file.exists()) {
 
 217       createWikiFile(file);
 
 221   protected IFile getWikiFile(IFile file, String word) {
 
 222     String wikiFileName = Util.getWikiFileName(word, file, WikiEditorPlugin.HTML_OUTPUT_PATH);
 
 223     IPath path = new Path(wikiFileName);
 
 224     return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
 
 228    * Creates a folder resource handle for the folder with the given workspace path. This method does not create the folder resource;
 
 229    * this is the responsibility of <code>createFolder</code>.
 
 232    *          the path of the folder resource to create a handle for
 
 233    * @return the new folder resource handle
 
 236   private static IFolder createFolderHandle(IPath folderPath) {
 
 237     return IDEWorkbenchPlugin.getPluginWorkspace().getRoot().getFolder(folderPath);
 
 240   private static void createFolder(IFolder folderHandle, IProgressMonitor monitor) throws CoreException {
 
 242       // Create the folder resource in the workspace
 
 243       // Recursive to create any folders which do not exist already
 
 244       if (!folderHandle.exists()) {
 
 245         IContainer parent = folderHandle.getParent();
 
 246         if (parent instanceof IFolder && (!((IFolder) parent).exists())) {
 
 247           createFolder((IFolder) parent, monitor);
 
 249         //                  if (linkTargetPath != null)
 
 250         //                              folderHandle.createLink(linkTargetPath, IResource.ALLOW_MISSING_LOCAL, monitor);
 
 252         folderHandle.create(false, true, monitor);
 
 254     } catch (CoreException e) {
 
 255       // If the folder already existed locally, just refresh to get contents
 
 256       if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED)
 
 257         folderHandle.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 500));
 
 263   private void createWikiFile(IFile file) throws CoreException {
 
 264     IContainer parent = file.getParent();
 
 265     if (parent instanceof IFolder && (!((IFolder) parent).exists())) {
 
 266       createFolder((IFolder) parent, null);
 
 268     String newText = WikiEditorPlugin.AUTOMATICALLY_CREATED;
 
 269     byte[] buffer = newText.getBytes();
 
 270     ByteArrayInputStream source = new ByteArrayInputStream(buffer);
 
 271     file.create(source, true, null);