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