bbfd7a7eb66f0c907aba1363eaea80ae1f57026e
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.wiki / src / net / sourceforge / phpeclipse / wiki / actions / mediawiki / DownloadWikiLinkEditorAction.java
1 package net.sourceforge.phpeclipse.wiki.actions.mediawiki;
2 //Parts of this sources are copied and modified from the jEdit Wikipedia plugin:
3 //http://www.djini.de/software/wikipedia/index.html
4 //
5 //The modified sources are available under the "Common Public License"
6 //with permission from the original author: Daniel Wunsch
7
8 import java.io.ByteArrayInputStream;
9
10 import net.sourceforge.phpeclipse.wiki.actions.mediawiki.connect.MediaWikiConnector;
11 import net.sourceforge.phpeclipse.wiki.editor.WikiEditor;
12 import net.sourceforge.phpeclipse.wiki.editor.WikiEditorPlugin;
13 import net.sourceforge.phpeclipse.wiki.preferences.Util;
14
15 import org.eclipse.core.resources.IContainer;
16 import org.eclipse.core.resources.IFile;
17 import org.eclipse.core.resources.IFolder;
18 import org.eclipse.core.resources.IResource;
19 import org.eclipse.core.resources.IResourceStatus;
20 import org.eclipse.core.resources.ResourcesPlugin;
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.IPath;
23 import org.eclipse.core.runtime.IProgressMonitor;
24 import org.eclipse.core.runtime.Path;
25 import org.eclipse.core.runtime.SubProgressMonitor;
26 import org.eclipse.jface.action.IAction;
27 import org.eclipse.jface.text.BadLocationException;
28 import org.eclipse.jface.text.IDocument;
29 import org.eclipse.jface.text.ITextSelection;
30 import org.eclipse.jface.text.TextSelection;
31 import org.eclipse.jface.viewers.ISelection;
32 import org.eclipse.ui.IEditorActionDelegate;
33 import org.eclipse.ui.IEditorPart;
34 import org.eclipse.ui.IFileEditorInput;
35 import org.eclipse.ui.IWorkbenchWindow;
36 import org.eclipse.ui.ide.IDE;
37 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
38 import org.eclipse.ui.texteditor.AbstractTextEditor;
39
40 public final class DownloadWikiLinkEditorAction implements IEditorActionDelegate {
41
42   private IWorkbenchWindow window; 
43
44   private AbstractTextEditor fEditor;
45
46   public void dispose() {
47   }
48
49   public void init(IWorkbenchWindow window) {
50     this.window = window;
51   }
52
53   public void selectionChanged(IAction action, ISelection selection) {
54     if (selection.isEmpty()) {
55       return;
56     }
57     if (selection instanceof TextSelection) {
58       action.setEnabled(true);
59       return;
60     }
61     if (window.getActivePage() != null && window.getActivePage().getActivePart() != null) {
62       action.setEnabled(window.getActivePage().getActivePart().getClass().equals(WikiEditor.class));
63     }
64   }
65
66   public void run(IAction action) {
67     if (fEditor == null) {
68       IEditorPart targetEditor = window.getActivePage().getActiveEditor();
69       if (targetEditor != null && (targetEditor instanceof AbstractTextEditor)) {
70         fEditor = (AbstractTextEditor) targetEditor;
71       }
72     }
73     if (fEditor != null) {
74       openWikiLinkOnSelection();
75     }
76   }
77
78   public void setActiveEditor(IAction action, IEditorPart targetEditor) {
79     if (targetEditor != null && (targetEditor instanceof AbstractTextEditor)) {
80       fEditor = (AbstractTextEditor) targetEditor;
81     }
82   }
83
84   public static String getWikiString(AbstractTextEditor editor, IDocument document, int initialPos) {
85     try {
86       int pos = initialPos;
87       int line = document.getLineOfOffset(pos);
88       int start = document.getLineOffset(line);
89       int end = start + document.getLineInformation(line).getLength();
90
91       /*
92        * 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
93        * determining the TextRegion at the cursor position
94        */
95       if (pos > end) {
96         pos = end;
97       }
98
99       int offsetInLine = pos - start;
100       String word = document.get(start, end - start);
101       int wordlen = word.length();
102       int wikiLinkStart = -1;
103       int wikiLinkEnd = -1;
104
105       for (int i = offsetInLine; i < wordlen; i++) {
106         if (word.charAt(i) == ']' && i < wordlen - 1 && word.charAt(i + 1) == ']') {
107           wikiLinkEnd = i;
108           break;
109         }
110         if (word.charAt(i) == '|') {
111           wikiLinkEnd = i;
112           break;
113         }
114         if (word.charAt(i) == '#') {
115           wikiLinkEnd = i;
116           break;
117         }
118       }
119       for (int i = offsetInLine; i >= 0; i--) {
120         if (word.charAt(i) == '[' && i > 0 && word.charAt(i - 1) == '[') {
121           wikiLinkStart = i + 1;
122           break;
123         }
124         if (word.charAt(i) == '|') { // links wih different description
125           wikiLinkEnd = i;
126         }
127         if (word.charAt(i) == '#') { // for links with anchors
128           wikiLinkEnd = i;
129         }
130       }
131       if (wikiLinkStart != (-1) && wikiLinkEnd != (-1) && wikiLinkStart < wikiLinkEnd) {
132         return new String(word.toCharArray(), wikiLinkStart, wikiLinkEnd - wikiLinkStart);
133       }
134     } catch (BadLocationException e) {
135
136     }
137     return "";
138   }
139
140   public IDocument getDocument() {
141     IDocument doc = fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput());
142     return doc;
143   }
144
145   public void openWikiLinkOnSelection() {
146     IDocument doc = getDocument();
147     ITextSelection selection = (ITextSelection) fEditor.getSelectionProvider().getSelection();
148     int pos = selection.getOffset();
149     String textRegion = getWikiString(fEditor, doc, pos);
150     IFileEditorInput ei = (IFileEditorInput) fEditor.getEditorInput();
151     openWikiFile(ei.getFile(), textRegion);
152   }
153
154   void openWikiFile(IFile cfile, String word) {
155     if (word != null && !word.equals("")) {
156       IFile file = getWikiFile(cfile, word);
157       try {
158         createNewFileIfNeeded(file, word);
159         
160         //                              if (WikiEditorPlugin.getDefault().getPreferenceStore().getBoolean(WikiConstants.REUSE_EDITOR)) {
161         //                                      saveIfNeeded();
162         //                                      getActivePage().reuseEditor(reusableEditor, new FileEditorInput(file));
163         //                              } else {
164         IEditorPart part = IDE.openEditor(WikiEditorPlugin.getDefault().getActivePage(), file, true);
165         if (part != null && (part instanceof AbstractTextEditor)) {
166           AbstractTextEditor newEditor = (AbstractTextEditor) part;
167           word = Util.titleToDB(word);
168           String wikiText = MediaWikiConnector.getWikiRawText(word, "http://en.wikibooks.org/w/wiki.phtml");
169           if (wikiText!=null) {
170             IDocument doc = newEditor.getDocumentProvider().getDocument(newEditor.getEditorInput());
171             doc.set(wikiText);
172           }
173         }
174         
175         
176         //                                      redrawText();
177         //                              }
178       } catch (Exception e) {
179         //                        WikiEditorPlugin.getDefault().logAndReport(WikiEditorPlugin.getResourceString(WikiConstants.RESOURCE_WIKI_ERROR_DIALOGUE_OPEN_WIKI_FILE_TITLE),
180         // WikiPlugin.getResourceString(WikiConstants.RESOURCE_WIKI_ERROR_DIALOGUE_OPEN_WIKI_FILE_TEXT), e);
181       }
182     } 
183   }
184
185   private void createNewFileIfNeeded(IFile file, String word) throws CoreException {
186     if (!file.exists()) {
187       createWikiFile(file, word);
188     }
189   }
190
191   private IFile getWikiFile(IFile file, String word) {
192     String wikiFileName = Util.getWikiFileName(word, file, WikiEditorPlugin.HTML_OUTPUT_PATH);
193     IPath path = new Path(wikiFileName);
194     return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
195   }
196
197   /**
198    * Creates a folder resource handle for the folder with the given workspace path. This method does not create the folder resource;
199    * this is the responsibility of <code>createFolder</code>.
200    * 
201    * @param folderPath
202    *          the path of the folder resource to create a handle for
203    * @return the new folder resource handle
204    * @see #createFolder
205    */
206   private IFolder createFolderHandle(IPath folderPath) {
207     return IDEWorkbenchPlugin.getPluginWorkspace().getRoot().getFolder(folderPath);
208   }
209
210   private void createFolder(IFolder folderHandle, IProgressMonitor monitor) throws CoreException {
211     try {
212       // Create the folder resource in the workspace
213       // Recursive to create any folders which do not exist already
214       if (!folderHandle.exists()) {
215         IContainer parent = folderHandle.getParent();
216         if (parent instanceof IFolder && (!((IFolder) parent).exists())) {
217           createFolder((IFolder) parent, monitor);
218         }
219         //                  if (linkTargetPath != null)
220         //                              folderHandle.createLink(linkTargetPath, IResource.ALLOW_MISSING_LOCAL, monitor);
221         //                  else
222         folderHandle.create(false, true, monitor);
223       }
224     } catch (CoreException e) {
225       // If the folder already existed locally, just refresh to get contents
226       if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED)
227         folderHandle.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 500));
228       else
229         throw e;
230     }
231   }
232
233   private void createWikiFile(IFile file, String word) throws CoreException {
234     IContainer parent = file.getParent();
235     if (parent instanceof IFolder && (!((IFolder) parent).exists())) {
236       createFolder((IFolder) parent, null);
237     }
238     String newText = "<!--" + word + "-->";
239     byte[] buffer = newText.getBytes();
240     ByteArrayInputStream source = new ByteArrayInputStream(buffer);
241     file.create(source, true, null);
242   }
243
244 }