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