* added a first PDF Exporter (menu File->Export...)
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.wiki / src / net / sourceforge / phpeclipse / wiki / builder / CreatePageAction.java
1 package net.sourceforge.phpeclipse.wiki.builder;
2
3 import java.io.BufferedInputStream;
4 import java.io.File;
5 import java.io.FileNotFoundException;
6 import java.io.FileOutputStream;
7 import java.io.FileWriter;
8 import java.io.IOException;
9 import java.io.InputStream;
10 import java.io.InputStreamReader;
11 import java.util.Iterator;
12
13 import net.sourceforge.phpeclipse.wiki.editor.WikiEditorPlugin;
14 import net.sourceforge.phpeclipse.wiki.preferences.Util;
15 import net.sourceforge.phpeclipse.wiki.renderer.IContentRenderer;
16 import net.sourceforge.phpeclipse.wiki.renderer.RendererFactory;
17
18 import org.eclipse.core.resources.IFile;
19 import org.eclipse.core.resources.IResource;
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.jface.action.IAction;
22 import org.eclipse.jface.viewers.ISelection;
23 import org.eclipse.jface.viewers.ISelectionProvider;
24 import org.eclipse.jface.viewers.StructuredSelection;
25 import org.eclipse.ui.IActionDelegate;
26 import org.eclipse.ui.IObjectActionDelegate;
27 import org.eclipse.ui.IWorkbenchPart;
28
29 /**
30  * Create a static HTML page
31  */
32 public class CreatePageAction implements IObjectActionDelegate {
33   /**
34    * Constant for an empty char array
35    */
36   public static final char[] NO_CHAR = new char[0];
37
38   private static final int DEFAULT_READING_SIZE = 8192;
39
40   private IWorkbenchPart workbenchPart;
41
42   /**
43    *  
44    */
45   public CreatePageAction() {
46     super();
47   }
48
49   /**
50    * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
51    */
52   public void setActivePart(IAction action, IWorkbenchPart targetPart) {
53     workbenchPart = targetPart;
54   }
55
56   public void run(IAction action) {
57     ISelectionProvider selectionProvider = null;
58     selectionProvider = workbenchPart.getSite().getSelectionProvider();
59
60     StructuredSelection selection = null;
61     selection = (StructuredSelection) selectionProvider.getSelection();
62
63     //Shell shell = null;
64     Iterator iterator = null;
65     iterator = selection.iterator();
66     while (iterator.hasNext()) {
67       //  obj => selected object in the view
68       Object obj = iterator.next();
69
70       // is it a resource
71       if (obj instanceof IResource) {
72         IResource resource = (IResource) obj;
73
74         // check if it's a file resource
75         switch (resource.getType()) {
76
77         case IResource.FILE:
78           createPage((IFile) resource);
79         }
80       }
81     }
82   }
83
84   /**
85    * @see IActionDelegate#selectionChanged(IAction, ISelection)
86    */
87   public void selectionChanged(IAction action, ISelection selection) {
88   }
89
90   public static void createFragmentPage(IFile file, StringBuffer htmlBuffer) {
91     BufferedInputStream stream = null;
92     try {
93 //      String templateFileName = Util.getLocalTemplate(file);
94       //    String cssUrl = Util.getLocalCssUrl(file);
95       String srcBasePath = Util.getWikiTextsPath(file);
96       String binBasePath = Util.getProjectsWikiOutputPath(file.getProject(), WikiEditorPlugin.HTML_OUTPUT_PATH);
97       IContentRenderer renderer = RendererFactory.createContentRenderer(file.getProject());
98       stream = new BufferedInputStream(file.getContents());
99
100       String fileName = Util.getHTMLFileName(file, binBasePath, srcBasePath);
101       String content = new String(getInputStreamAsCharArray(stream, -1, "utf-8"));
102       String filePath = file.getLocation().toString(); // file.getProjectRelativePath().toString()
103       if (filePath.startsWith(srcBasePath)) {
104         filePath = filePath.substring(srcBasePath.length() + 1);
105       }
106       // calculate the <i>depth</i> of the file (i.e. ../../../ as much as needed)
107       int index = 0;
108       int level = 0;
109       while (index >= 0) {
110         index = fileName.indexOf('/', index);
111         if (index >= 0) {
112           level++;
113           index++;
114         }
115       }
116       renderer.render(null, content, htmlBuffer, level, false);
117
118     } catch (Exception e) {
119       e.printStackTrace();
120     } finally {
121       try {
122         if (stream != null) {
123           stream.close();
124         }
125       } catch (IOException e) {
126       }
127     }
128
129   }
130
131   public static void createPage(IFile file) {
132     String templateFileName = Util.getLocalTemplate(file);
133     String cssUrl = Util.getLocalCssUrl(file);
134     String srcBasePath = Util.getWikiTextsPath(file);
135     String binBasePath = Util.getProjectsWikiOutputPath(file.getProject(), WikiEditorPlugin.HTML_OUTPUT_PATH);
136     createPage(templateFileName, file, binBasePath, srcBasePath);
137   }
138
139   public static void createPage(String templateFileName, IFile file, String binBasePath, String srcBasePath) {
140     //          only interested in files with the "wp" extension
141     if ("wp".equalsIgnoreCase(file.getFileExtension())) {
142       try {
143         IContentRenderer renderer = RendererFactory.createContentRenderer(file.getProject());
144         convertWikiFile(templateFileName, file, binBasePath, srcBasePath, renderer);
145       } catch (InstantiationException e) {
146         // TODO Auto-generated catch block
147         e.printStackTrace();
148       } catch (IllegalAccessException e) {
149         // TODO Auto-generated catch block
150         e.printStackTrace();
151       } catch (ClassNotFoundException e) {
152         // TODO Auto-generated catch block
153         e.printStackTrace();
154       } catch (CoreException e1) {
155         // TODO Auto-generated catch block
156         e1.printStackTrace();
157       } catch (Exception e) {
158         // TODO Auto-generated catch block
159         e.printStackTrace();
160       }
161     } else {
162       String fname = file.getName().toLowerCase();
163       if ((fname.charAt(0) == '.') || "project.index".equals(fname) || "cvs".equals(fname) || "entries".equals(fname)
164           || "repository".equals(fname) || "root".equals(fname)) {
165         // ignore meta information
166         return;
167       }
168       // copy the file
169       FileOutputStream output = null;
170       InputStream contentStream = null;
171
172       try {
173         String filename = Util.getHTMLFileName(file, binBasePath, srcBasePath);
174         if (filename != null) {
175           int index = filename.lastIndexOf('/');
176           if (index >= 0) {
177             File ioFile = new File(filename.substring(0, index));
178             if (!ioFile.isDirectory()) {
179               ioFile.mkdirs();
180             }
181           }
182           output = new FileOutputStream(filename);
183
184           contentStream = file.getContents(false);
185           int chunkSize = contentStream.available();
186           byte[] readBuffer = new byte[chunkSize];
187           int n = contentStream.read(readBuffer);
188
189           while (n > 0) {
190             output.write(readBuffer);
191             n = contentStream.read(readBuffer);
192           }
193         }
194       } catch (Exception e) {
195
196       } finally {
197         try {
198           if (output != null)
199             output.close();
200           if (contentStream != null)
201             contentStream.close();
202         } catch (IOException e1) {
203         }
204       }
205     }
206   }
207
208   public static void convertWikiFile(String templateFileName, IFile file, String binBasePath, String srcBasePath,
209       IContentRenderer renderer) throws CoreException {
210     StringBuffer htmlBuffer = new StringBuffer();
211     convertWikiBuffer(templateFileName, htmlBuffer, file, renderer, true);
212     String htmlName = Util.getHTMLFileName(file, binBasePath, srcBasePath);
213     if (htmlName != null) {
214       writeHTMLFile(htmlBuffer, htmlName);
215     }
216   }
217
218   public static void getWikiBuffer(StringBuffer htmlBuffer, IFile file) throws CoreException {
219     BufferedInputStream stream = new BufferedInputStream(file.getContents());
220     try {
221       htmlBuffer.append(getInputStreamAsCharArray(stream, -1, null));
222       return;
223       //new String(getInputStreamAsCharArray(stream, -1, null));
224     } catch (IOException e) {
225       e.printStackTrace();
226     } finally {
227       try {
228         if (stream != null) {
229           stream.close();
230         }
231       } catch (IOException e) {
232       }
233     }
234     return;
235   }
236
237   public static void convertWikiBuffer(String templateFileName, StringBuffer htmlBuffer, IFile file, IContentRenderer renderer,
238       boolean completeHTML) throws CoreException {
239     BufferedInputStream stream = new BufferedInputStream(file.getContents());
240     try {
241       String content = new String(getInputStreamAsCharArray(stream, -1, null));
242       String srcPath = Util.getWikiTextsPath(file);
243       String filePath = file.getLocation().toString(); // file.getProjectRelativePath().toString()
244       if (filePath.startsWith(srcPath)) {
245         filePath = filePath.substring(srcPath.length() + 1);
246       }
247       createWikiBuffer(templateFileName, htmlBuffer, filePath, content, renderer, completeHTML);
248     } catch (IOException e) {
249       e.printStackTrace();
250     } finally {
251       try {
252         if (stream != null) {
253           stream.close();
254         }
255       } catch (IOException e) {
256       }
257     }
258   }
259
260   /**
261    * @param htmlBuffer
262    * @param fileName
263    * @param content
264    * @param renderer
265    */
266   public static void createWikiBuffer(String templateFileName, StringBuffer htmlBuffer, String fileName, String content,
267       IContentRenderer renderer, boolean completeHTML) {
268     // calculate the <i>depth</i> of the file (i.e. ../../../ as much as needed)
269     int index = 0;
270     int level = 0;
271     while (index >= 0) {
272       index = fileName.indexOf('/', index);
273       if (index >= 0) {
274         level++;
275         index++;
276       }
277     }
278     renderer.render(templateFileName, content, htmlBuffer, level, completeHTML);
279   }
280
281   public static void writeHTMLFile(StringBuffer buffer, String filename) {
282     int index = filename.lastIndexOf('/');
283     if (index >= 0) {
284       File file = new File(filename.substring(0, index));
285       if (!file.isDirectory()) {
286         file.mkdirs();
287       }
288     }
289     FileWriter fileWriter;
290     try {
291       fileWriter = new FileWriter(filename);
292       fileWriter.write(buffer.toString());
293       fileWriter.close();
294     } catch (FileNotFoundException e) {
295       // ignore exception; project is deleted by fUser
296     } catch (IOException e) {
297       // TODO Auto-generated catch block
298       e.printStackTrace();
299     }
300   }
301
302   /**
303    * Returns the given input stream's contents as a character array. If a length is specified (ie. if length != -1), only length
304    * chars are returned. Otherwise all chars in the stream are returned. Note this doesn't close the stream.
305    * 
306    * @throws IOException
307    *           if a problem occured reading the stream.
308    */
309   public static char[] getInputStreamAsCharArray(InputStream stream, int length, String encoding) throws IOException {
310     InputStreamReader reader = null;
311     reader = encoding == null ? new InputStreamReader(stream) : new InputStreamReader(stream, encoding);
312     char[] contents;
313     if (length == -1) {
314       contents = NO_CHAR;
315       int contentsLength = 0;
316       int amountRead = -1;
317       do {
318         int amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE); // read at least 8K
319
320         // resize contents if needed
321         if (contentsLength + amountRequested > contents.length) {
322           System.arraycopy(contents, 0, contents = new char[contentsLength + amountRequested], 0, contentsLength);
323         }
324
325         // read as many chars as possible
326         amountRead = reader.read(contents, contentsLength, amountRequested);
327
328         if (amountRead > 0) {
329           // remember length of contents
330           contentsLength += amountRead;
331         }
332       } while (amountRead != -1);
333
334       // resize contents if necessary
335       if (contentsLength < contents.length) {
336         System.arraycopy(contents, 0, contents = new char[contentsLength], 0, contentsLength);
337       }
338     } else {
339       contents = new char[length];
340       int len = 0;
341       int readSize = 0;
342       while ((readSize != -1) && (len != length)) {
343         // See PR 1FMS89U
344         // We record first the read size. In this case len is the actual
345         // read size.
346         len += readSize;
347         readSize = reader.read(contents, len, length - len);
348       }
349       // See PR 1FMS89U
350       // Now we need to resize in case the default encoding used more than
351       // one byte for each
352       // character
353       if (len != length)
354         System.arraycopy(contents, 0, (contents = new char[len]), 0, len);
355     }
356
357     return contents;
358   }
359 }