initial contribution
[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 createPage(IFile file) {
91     String srcBasePath = Util.getWikiTextsPath(file);
92     String binBasePath = Util.getProjectsWikiOutputPath(file.getProject(), WikiEditorPlugin.HTML_OUTPUT_PATH);
93     createPage(file, binBasePath, srcBasePath);
94   }
95
96   public static void createPage(IFile file, String binBasepath, String srcBasePath) {
97     //          only interested in files with the "wp" extension
98     if ("wp".equalsIgnoreCase(file.getFileExtension())) {
99       try {
100         IContentRenderer renderer = RendererFactory.createContentRenderer(file.getProject());
101         convertWikiFile(file, binBasepath, srcBasePath, renderer);
102       } catch (InstantiationException e) {
103         // TODO Auto-generated catch block
104         e.printStackTrace();
105       } catch (IllegalAccessException e) {
106         // TODO Auto-generated catch block
107         e.printStackTrace();
108       } catch (ClassNotFoundException e) {
109         // TODO Auto-generated catch block
110         e.printStackTrace();
111       } catch (CoreException e1) {
112         // TODO Auto-generated catch block
113         e1.printStackTrace();
114       }
115     } else {
116       String fname = file.getName().toLowerCase();
117       if ((fname.charAt(0) == '.') || "project.index".equals(fname) || "cvs".equals(fname) || "entries".equals(fname)
118           || "repository".equals(fname) || "root".equals(fname)) {
119         // ignore meta information
120         return;
121       }
122       // copy the file
123       FileOutputStream output = null;
124       InputStream contentStream = null;
125
126       try {
127         String filename = Util.getHTMLFileName(file, binBasepath, srcBasePath);
128         if (filename != null) {
129           int index = filename.lastIndexOf('/');
130           if (index >= 0) {
131             File ioFile = new File(filename.substring(0, index));
132             if (!ioFile.isDirectory()) {
133               ioFile.mkdirs();
134             }
135           }
136           output = new FileOutputStream(filename);
137
138           contentStream = file.getContents(false);
139           int chunkSize = contentStream.available();
140           byte[] readBuffer = new byte[chunkSize];
141           int n = contentStream.read(readBuffer);
142
143           while (n > 0) {
144             output.write(readBuffer);
145             n = contentStream.read(readBuffer);
146           }
147         }
148       } catch (Exception e) {
149
150       } finally {
151         try {
152           if (output != null)
153             output.close();
154           if (contentStream != null)
155             contentStream.close();
156         } catch (IOException e1) {
157         }
158       }
159     }
160   }
161
162   public static void convertWikiFile(IFile file, String binBasePath, String srcBasePath, IContentRenderer renderer)
163       throws CoreException {
164     StringBuffer htmlBuffer = new StringBuffer();
165     convertWikiBuffer(htmlBuffer, file, renderer, true);
166     String htmlName = Util.getHTMLFileName(file, binBasePath, srcBasePath);
167     if (htmlName != null) {
168       writeHTMLFile(htmlBuffer, htmlName);
169     }
170   }
171
172   public static void getWikiBuffer(StringBuffer htmlBuffer, IFile file) throws CoreException {
173     BufferedInputStream stream = new BufferedInputStream(file.getContents());
174     try {
175       htmlBuffer.append(getInputStreamAsCharArray(stream, -1, null));
176       return;
177       //new String(getInputStreamAsCharArray(stream, -1, null));
178     } catch (IOException e) {
179       e.printStackTrace();
180     } finally {
181       try {
182         if (stream != null) {
183           stream.close();
184         }
185       } catch (IOException e) {
186       }
187     }
188     return;
189   }
190
191   public static void convertWikiBuffer(StringBuffer htmlBuffer, IFile file, IContentRenderer renderer, boolean completeHTML)
192       throws CoreException {
193     BufferedInputStream stream = new BufferedInputStream(file.getContents());
194     try {
195       String content = new String(getInputStreamAsCharArray(stream, -1, null));
196       String srcPath = Util.getWikiTextsPath(file);
197       String filePath = file.getLocation().toString(); // file.getProjectRelativePath().toString()
198       if (filePath.startsWith(srcPath)) {
199         filePath = filePath.substring(srcPath.length()+1);
200       }
201       createWikiBuffer(htmlBuffer, filePath, content, renderer, completeHTML);
202     } catch (IOException e) {
203       e.printStackTrace();
204     } finally {
205       try {
206         if (stream != null) {
207           stream.close();
208         }
209       } catch (IOException e) {
210       }
211     }
212   }
213
214   /**
215    * @param htmlBuffer
216    * @param fileName
217    * @param content
218    * @param renderer
219    */
220   public static void createWikiBuffer(StringBuffer htmlBuffer, String fileName, String content, IContentRenderer renderer,
221       boolean completeHTML) {
222     // calculate the <i>depth</i> of the file (i.e. ../../../ as much as needed)
223     int index = 0;
224     int level = 0;
225     while (index >= 0) {
226       index = fileName.indexOf('/', index);
227       if (index >= 0) {
228         level++;
229         index++;
230       }
231     }
232     renderer.render(content, htmlBuffer, level, completeHTML);
233   }
234
235   public static void writeHTMLFile(StringBuffer buffer, String filename) {
236     int index = filename.lastIndexOf('/');
237     if (index >= 0) {
238       File file = new File(filename.substring(0, index));
239       if (!file.isDirectory()) {
240         file.mkdirs();
241       }
242     }
243     FileWriter fileWriter;
244     try {
245       fileWriter = new FileWriter(filename);
246       fileWriter.write(buffer.toString());
247       fileWriter.close();
248     } catch (FileNotFoundException e) {
249       // ignore exception; project is deleted by fUser
250     } catch (IOException e) {
251       // TODO Auto-generated catch block
252       e.printStackTrace();
253     }
254   }
255
256   /**
257    * Returns the given input stream's contents as a character array. If a length is specified (ie. if length != -1), only length
258    * chars are returned. Otherwise all chars in the stream are returned. Note this doesn't close the stream.
259    * 
260    * @throws IOException
261    *           if a problem occured reading the stream.
262    */
263   public static char[] getInputStreamAsCharArray(InputStream stream, int length, String encoding) throws IOException {
264     InputStreamReader reader = null;
265     reader = encoding == null ? new InputStreamReader(stream) : new InputStreamReader(stream, encoding);
266     char[] contents;
267     if (length == -1) {
268       contents = NO_CHAR;
269       int contentsLength = 0;
270       int amountRead = -1;
271       do {
272         int amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE); // read at least 8K
273
274         // resize contents if needed
275         if (contentsLength + amountRequested > contents.length) {
276           System.arraycopy(contents, 0, contents = new char[contentsLength + amountRequested], 0, contentsLength);
277         }
278
279         // read as many chars as possible
280         amountRead = reader.read(contents, contentsLength, amountRequested);
281
282         if (amountRead > 0) {
283           // remember length of contents
284           contentsLength += amountRead;
285         }
286       } while (amountRead != -1);
287
288       // resize contents if necessary
289       if (contentsLength < contents.length) {
290         System.arraycopy(contents, 0, contents = new char[contentsLength], 0, contentsLength);
291       }
292     } else {
293       contents = new char[length];
294       int len = 0;
295       int readSize = 0;
296       while ((readSize != -1) && (len != length)) {
297         // See PR 1FMS89U
298         // We record first the read size. In this case len is the actual
299         // read size.
300         len += readSize;
301         readSize = reader.read(contents, len, length - len);
302       }
303       // See PR 1FMS89U
304       // Now we need to resize in case the default encoding used more than
305       // one byte for each
306       // character
307       if (len != length)
308         System.arraycopy(contents, 0, (contents = new char[len]), 0, len);
309     }
310
311     return contents;
312   }
313 }