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 (Exception 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 if (wikiTitle != null && !wikiTitle.equals("")) {
149 IFileEditorInput ei = (IFileEditorInput) editor.getEditorInput();
150 openWikiFile(ei.getFile(), wikiTitle, true);
154 // public void openWikiUrl(IProject project, String wikiTitle) {
155 // if (wikiTitle != null && !wikiTitle.equals("")) {
156 // IFile cfile = project.getFile("dummy.wp");
157 // IFile file = getWikiFile(cfile, wikiTitle);
159 // createNewFileIfNeeded(file, wikiTitle);
161 // IDE.openEditor(WikiEditorPlugin.getDefault().getActivePage(), file, true);
162 // } catch (Exception e) {
164 // WikiEditorPlugin.getDefault().logAndReport(WikiEditorPlugin.getResourceString(WikiConstants.RESOURCE_WIKI_ERROR_DIALOGUE_OPEN_WIKI_FILE_TITLE),
165 // // WikiPlugin.getResourceString(WikiConstants.RESOURCE_WIKI_ERROR_DIALOGUE_OPEN_WIKI_FILE_TEXT), e);
170 protected void openWikiFile(IFile cfile, String wikiTitle, boolean openEditor) {
171 if (wikiTitle != null && !wikiTitle.equals("")) {
172 IFile file = getWikiFile(cfile, wikiTitle);
174 createNewFileIfNeeded(file, wikiTitle);
176 Page page = new Page("", wikiTitle, "");
177 page.createXMLFile(file, false);
178 // createXMLFile(wikiTitle, file, false);
180 IDE.openEditor(WikiEditorPlugin.getDefault().getActivePage(), file, true);
181 } catch (Exception e) {
182 // WikiEditorPlugin.getDefault().logAndReport(WikiEditorPlugin.getResourceString(WikiConstants.RESOURCE_WIKI_ERROR_DIALOGUE_OPEN_WIKI_FILE_TITLE),
183 // WikiPlugin.getResourceString(WikiConstants.RESOURCE_WIKI_ERROR_DIALOGUE_OPEN_WIKI_FILE_TEXT), e);
191 * @throws CoreException
193 private void createXMLFile(String wikiTitle, IFile file, boolean modify) throws CoreException {
194 String srcBasePath = Util.getWikiTextsPath(file);
195 String binBasePath = Util.getProjectsWikiOutputPath(file.getProject(), WikiEditorPlugin.HTML_OUTPUT_PATH);
197 String filename = Util.getXMLFileName(file, binBasePath, srcBasePath);
198 IPath path = new Path(filename);
199 IFile xmlFile = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
200 IContainer parent = xmlFile.getParent();
201 if (parent instanceof IFolder && (!((IFolder) parent).exists())) {
202 Util.createFolder((IFolder) parent, null);
204 Page page = new Page("", wikiTitle, "");
205 byte[] buffer = XStreamManager.toXML(page).getBytes();
206 ByteArrayInputStream source = new ByteArrayInputStream(buffer);
207 if (!xmlFile.exists()) {
208 // only if file doesn't exists
209 xmlFile.create(source, true, null);
212 xmlFile.setContents(source, true, true, null);
217 protected void createNewFileIfNeeded(IFile file, String word) throws CoreException {
218 if (!file.exists()) {
219 createWikiFile(file);
223 protected IFile getWikiFile(IFile file, String word) {
224 String wikiFileName = Util.getWikiFileName(word, file, WikiEditorPlugin.HTML_OUTPUT_PATH);
225 IPath path = new Path(wikiFileName);
226 return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
230 * Creates a folder resource handle for the folder with the given workspace path. This method does not create the folder resource;
231 * this is the responsibility of <code>createFolder</code>.
234 * the path of the folder resource to create a handle for
235 * @return the new folder resource handle
238 private static IFolder createFolderHandle(IPath folderPath) {
239 return IDEWorkbenchPlugin.getPluginWorkspace().getRoot().getFolder(folderPath);
242 private static void createFolder(IFolder folderHandle, IProgressMonitor monitor) throws CoreException {
244 // Create the folder resource in the workspace
245 // Recursive to create any folders which do not exist already
246 if (!folderHandle.exists()) {
247 IContainer parent = folderHandle.getParent();
248 if (parent instanceof IFolder && (!((IFolder) parent).exists())) {
249 createFolder((IFolder) parent, monitor);
251 // if (linkTargetPath != null)
252 // folderHandle.createLink(linkTargetPath, IResource.ALLOW_MISSING_LOCAL, monitor);
254 folderHandle.create(false, true, monitor);
256 } catch (CoreException e) {
257 // If the folder already existed locally, just refresh to get contents
258 if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED)
259 folderHandle.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 500));
265 private void createWikiFile(IFile file) throws CoreException {
266 IContainer parent = file.getParent();
267 if (parent instanceof IFolder && (!((IFolder) parent).exists())) {
268 createFolder((IFolder) parent, null);
270 String newText = WikiEditorPlugin.AUTOMATICALLY_CREATED;
271 byte[] buffer = newText.getBytes();
272 ByteArrayInputStream source = new ByteArrayInputStream(buffer);
273 file.create(source, true, null);