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