''Open Wiki link'' and ''Create Files for Wiki link'' every new created file creates...
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.wiki / src / net / sourceforge / phpeclipse / wiki / actions / OpenWikiLinkEditorAction.java
1 package net.sourceforge.phpeclipse.wiki.actions;
2
3 import java.io.ByteArrayInputStream;
4
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;
10
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;
36
37 public class OpenWikiLinkEditorAction implements IEditorActionDelegate {
38
39   protected IWorkbenchWindow window;
40
41   protected AbstractTextEditor editor;
42
43   public void dispose() {
44   }
45
46   public void init(IWorkbenchWindow window) {
47     this.window = window;
48   }
49
50   public void selectionChanged(IAction action, ISelection selection) {
51     if (selection.isEmpty()) {
52       return;
53     }
54     if (selection instanceof TextSelection) {
55       action.setEnabled(true);
56       return;
57     }
58     if (window.getActivePage() != null && window.getActivePage().getActivePart() != null) {
59       action.setEnabled(window.getActivePage().getActivePart().getClass().equals(WikiEditor.class));
60     }
61   }
62
63   public void run(IAction action) {
64     if (editor == null) {
65       IEditorPart targetEditor = window.getActivePage().getActiveEditor();
66       if (targetEditor != null && (targetEditor instanceof AbstractTextEditor)) {
67         editor = (AbstractTextEditor) targetEditor;
68       }
69     }
70     if (editor != null) {
71       openWikiLinkOnSelection();
72     }
73   }
74
75   public void setActiveEditor(IAction action, IEditorPart targetEditor) {
76     if (targetEditor != null && (targetEditor instanceof AbstractTextEditor)) {
77       editor = (AbstractTextEditor) targetEditor;
78     }
79   }
80
81   public static String getWikiTitle(AbstractTextEditor editor, IDocument document, int initialPos) {
82     try {
83       int pos = initialPos;
84       int line = document.getLineOfOffset(pos);
85       int start = document.getLineOffset(line);
86       int end = start + document.getLineInformation(line).getLength();
87
88       /*
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
91        */
92       if (pos > end) {
93         pos = end;
94       }
95
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;
101
102       for (int i = offsetInLine; i < wordlen; i++) {
103         if (word.charAt(i) == ']' && i < wordlen - 1 && word.charAt(i + 1) == ']') {
104           wikiLinkEnd = i;
105           break;
106         }
107         if (word.charAt(i) == '|') {
108           wikiLinkEnd = i;
109           break;
110         }
111         if (word.charAt(i) == '#') {
112           wikiLinkEnd = i;
113           break;
114         }
115       }
116       for (int i = offsetInLine; i >= 0; i--) {
117         if (word.charAt(i) == '[' && i > 0 && word.charAt(i - 1) == '[') {
118           wikiLinkStart = i + 1;
119           break;
120         }
121         if (word.charAt(i) == '|') { // links with different description
122           wikiLinkEnd = i;
123         }
124         if (word.charAt(i) == '#') { // for links with anchors
125           wikiLinkEnd = i;
126         }
127       }
128       if (wikiLinkStart != (-1) && wikiLinkEnd != (-1) && wikiLinkStart < wikiLinkEnd) {
129         return new String(word.toCharArray(), wikiLinkStart, wikiLinkEnd - wikiLinkStart);
130       }
131     } catch (BadLocationException e) {
132
133     }
134     return "";
135   }
136
137   public IDocument getDocument() {
138     IDocument doc = editor.getDocumentProvider().getDocument(editor.getEditorInput());
139     return doc;
140   }
141
142   public void openWikiLinkOnSelection() {
143     IDocument doc = getDocument();
144     ITextSelection selection = (ITextSelection) editor.getSelectionProvider().getSelection();
145     int pos = selection.getOffset();
146
147     String wikiTitle = getWikiTitle(editor, doc, pos);
148     IFileEditorInput ei = (IFileEditorInput) editor.getEditorInput();
149     openWikiFile(ei.getFile(), wikiTitle, true);
150   }
151
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);
156   //      try {
157   //        createNewFileIfNeeded(file, wikiTitle);
158   //        
159   //        IDE.openEditor(WikiEditorPlugin.getDefault().getActivePage(), file, true);
160   //      } catch (Exception e) {
161   //        //
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);
164   //      }
165   //    }
166   //  }
167
168   protected void openWikiFile(IFile cfile, String wikiTitle, boolean openEditor) {
169     if (wikiTitle != null && !wikiTitle.equals("")) {
170       IFile file = getWikiFile(cfile, wikiTitle);
171       try {
172         createNewFileIfNeeded(file, wikiTitle);
173
174         Page page = new Page("", wikiTitle, "");
175         page.createXMLFile(file, false);
176 //        createXMLFile(wikiTitle, file, false);
177
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);
182       }
183     }
184   }
185
186   /**
187    * @param wikiTitle
188    * @param file
189    * @throws CoreException
190    */
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);
194
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);
201     }
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);
208     } else {
209       if (modify) {
210         xmlFile.setContents(source, true, true, null);
211       }
212     }
213   }
214
215   protected void createNewFileIfNeeded(IFile file, String word) throws CoreException {
216     if (!file.exists()) {
217       createWikiFile(file);
218     }
219   }
220
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);
225   }
226
227   /**
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>.
230    * 
231    * @param folderPath
232    *          the path of the folder resource to create a handle for
233    * @return the new folder resource handle
234    * @see #createFolder
235    */
236   private static IFolder createFolderHandle(IPath folderPath) {
237     return IDEWorkbenchPlugin.getPluginWorkspace().getRoot().getFolder(folderPath);
238   }
239
240   private static void createFolder(IFolder folderHandle, IProgressMonitor monitor) throws CoreException {
241     try {
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);
248         }
249         //                  if (linkTargetPath != null)
250         //                              folderHandle.createLink(linkTargetPath, IResource.ALLOW_MISSING_LOCAL, monitor);
251         //                  else
252         folderHandle.create(false, true, monitor);
253       }
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));
258       else
259         throw e;
260     }
261   }
262
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);
267     }
268     String newText = WikiEditorPlugin.AUTOMATICALLY_CREATED;
269     byte[] buffer = newText.getBytes();
270     ByteArrayInputStream source = new ByteArrayInputStream(buffer);
271     file.create(source, true, null);
272   }
273
274 }