package net.sourceforge.phpeclipse.wiki.builder; import java.io.BufferedInputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Iterator; import net.sourceforge.phpeclipse.wiki.editor.WikiEditorPlugin; import net.sourceforge.phpeclipse.wiki.preferences.Util; import net.sourceforge.phpeclipse.wiki.renderer.IContentRenderer; import net.sourceforge.phpeclipse.wiki.renderer.RendererFactory; import net.sourceforge.phpeclipse.wiki.renderer.StringUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.ui.IActionDelegate; import org.eclipse.ui.IObjectActionDelegate; import org.eclipse.ui.IWorkbenchPart; /** * Create a static HTML page */ public class CreatePageAction implements IObjectActionDelegate { /** * Constant for an empty char array */ public static final char[] NO_CHAR = new char[0]; private static final int DEFAULT_READING_SIZE = 8192; private IWorkbenchPart workbenchPart; /** * */ public CreatePageAction() { super(); } /** * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) */ public void setActivePart(IAction action, IWorkbenchPart targetPart) { workbenchPart = targetPart; } public void run(IAction action) { ISelectionProvider selectionProvider = null; selectionProvider = workbenchPart.getSite().getSelectionProvider(); StructuredSelection selection = null; selection = (StructuredSelection) selectionProvider.getSelection(); //Shell shell = null; Iterator iterator = null; iterator = selection.iterator(); while (iterator.hasNext()) { // obj => selected object in the view Object obj = iterator.next(); // is it a resource if (obj instanceof IResource) { IResource resource = (IResource) obj; // check if it's a file resource switch (resource.getType()) { case IResource.FILE: createPage((IFile) resource); } } } } /** * @see IActionDelegate#selectionChanged(IAction, ISelection) */ public void selectionChanged(IAction action, ISelection selection) { } public static boolean createFragmentPage(IFile file, StringBuffer htmlBuffer) { BufferedInputStream stream = null; boolean noContent = true; try { // String templateFileName = Util.getLocalTemplate(file); // String cssUrl = Util.getLocalCssUrl(file); String srcBasePath = Util.getWikiTextsPath(file); String binBasePath = Util.getProjectsWikiOutputPath(file.getProject(), WikiEditorPlugin.HTML_OUTPUT_PATH); IContentRenderer renderer = RendererFactory.createContentRenderer(file.getProject()); stream = new BufferedInputStream(file.getContents()); String fileName = Util.getHTMLFileName(file, binBasePath, srcBasePath); String content = new String(getInputStreamAsCharArray(stream, -1, "utf-8")); noContent = StringUtil.checkNoContent(content); String filePath = file.getLocation().toString(); // file.getProjectRelativePath().toString() if (filePath.startsWith(srcBasePath)) { filePath = filePath.substring(srcBasePath.length() + 1); } // calculate the depth of the file (i.e. ../../../ as much as needed) int index = 0; int level = 0; while (index >= 0) { index = fileName.indexOf('/', index); if (index >= 0) { level++; index++; } } renderer.render(null, content, htmlBuffer, level, false); } catch (Exception e) { e.printStackTrace(); } finally { try { if (stream != null) { stream.close(); } } catch (IOException e) { } } return noContent; } public static void createPage(IFile file) { String templateFileName = Util.getLocalTemplate(file); String cssUrl = Util.getLocalCssUrl(file); String srcBasePath = Util.getWikiTextsPath(file); String binBasePath = Util.getProjectsWikiOutputPath(file.getProject(), WikiEditorPlugin.HTML_OUTPUT_PATH); createPage(templateFileName, file, binBasePath, srcBasePath); } public static void createPage(String templateFileName, IFile file, String binBasePath, String srcBasePath) { // only interested in files with the "wp" extension if ("wp".equalsIgnoreCase(file.getFileExtension())) { try { IContentRenderer renderer = RendererFactory.createContentRenderer(file.getProject()); convertWikiFile(templateFileName, file, binBasePath, srcBasePath, renderer); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (CoreException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { String fname = file.getName().toLowerCase(); if ((fname.charAt(0) == '.') || "project.index".equals(fname) || "cvs".equals(fname) || "entries".equals(fname) || "repository".equals(fname) || "root".equals(fname)) { // ignore meta information return; } // copy the file FileOutputStream output = null; InputStream contentStream = null; try { String filename = Util.getHTMLFileName(file, binBasePath, srcBasePath); if (filename != null) { int index = filename.lastIndexOf('/'); if (index >= 0) { File ioFile = new File(filename.substring(0, index)); if (!ioFile.isDirectory()) { ioFile.mkdirs(); } } output = new FileOutputStream(filename); contentStream = file.getContents(false); int chunkSize = contentStream.available(); byte[] readBuffer = new byte[chunkSize]; int n = contentStream.read(readBuffer); while (n > 0) { output.write(readBuffer); n = contentStream.read(readBuffer); } } } catch (Exception e) { } finally { try { if (output != null) output.close(); if (contentStream != null) contentStream.close(); } catch (IOException e1) { } } } } public static void convertWikiFile(String templateFileName, IFile file, String binBasePath, String srcBasePath, IContentRenderer renderer) throws CoreException { StringBuffer htmlBuffer = new StringBuffer(); convertWikiBuffer(templateFileName, htmlBuffer, file, renderer, true); String htmlName = Util.getHTMLFileName(file, binBasePath, srcBasePath); if (htmlName != null) { writeHTMLFile(htmlBuffer, htmlName); } } public static void getWikiBuffer(StringBuffer htmlBuffer, IFile file) throws CoreException { BufferedInputStream stream = new BufferedInputStream(file.getContents()); try { htmlBuffer.append(getInputStreamAsCharArray(stream, -1, null)); return; //new String(getInputStreamAsCharArray(stream, -1, null)); } catch (IOException e) { e.printStackTrace(); } finally { try { if (stream != null) { stream.close(); } } catch (IOException e) { } } return; } public static void convertWikiBuffer(String templateFileName, StringBuffer htmlBuffer, IFile file, IContentRenderer renderer, boolean completeHTML) throws CoreException { BufferedInputStream stream = new BufferedInputStream(file.getContents()); try { String content = new String(getInputStreamAsCharArray(stream, -1, null)); String srcPath = Util.getWikiTextsPath(file); String filePath = file.getLocation().toString(); // file.getProjectRelativePath().toString() if (filePath.startsWith(srcPath)) { filePath = filePath.substring(srcPath.length() + 1); } createWikiBuffer(templateFileName, htmlBuffer, filePath, content, renderer, completeHTML); } catch (IOException e) { e.printStackTrace(); } finally { try { if (stream != null) { stream.close(); } } catch (IOException e) { } } } /** * @param htmlBuffer * @param fileName * @param content * @param renderer */ public static void createWikiBuffer(String templateFileName, StringBuffer htmlBuffer, String fileName, String content, IContentRenderer renderer, boolean completeHTML) { // calculate the depth of the file (i.e. ../../../ as much as needed) int index = 0; int level = 0; while (index >= 0) { index = fileName.indexOf('/', index); if (index >= 0) { level++; index++; } } renderer.render(templateFileName, content, htmlBuffer, level, completeHTML); } public static void writeHTMLFile(StringBuffer buffer, String filename) { int index = filename.lastIndexOf('/'); if (index >= 0) { File file = new File(filename.substring(0, index)); if (!file.isDirectory()) { file.mkdirs(); } } FileWriter fileWriter; try { fileWriter = new FileWriter(filename); fileWriter.write(buffer.toString()); fileWriter.close(); } catch (FileNotFoundException e) { // ignore exception; project is deleted by fUser } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * Returns the given input stream's contents as a character array. If a length is specified (ie. if length != -1), only length * chars are returned. Otherwise all chars in the stream are returned. Note this doesn't close the stream. * * @throws IOException * if a problem occured reading the stream. */ public static char[] getInputStreamAsCharArray(InputStream stream, int length, String encoding) throws IOException { InputStreamReader reader = null; reader = encoding == null ? new InputStreamReader(stream) : new InputStreamReader(stream, encoding); char[] contents; if (length == -1) { contents = NO_CHAR; int contentsLength = 0; int amountRead = -1; do { int amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE); // read at least 8K // resize contents if needed if (contentsLength + amountRequested > contents.length) { System.arraycopy(contents, 0, contents = new char[contentsLength + amountRequested], 0, contentsLength); } // read as many chars as possible amountRead = reader.read(contents, contentsLength, amountRequested); if (amountRead > 0) { // remember length of contents contentsLength += amountRead; } } while (amountRead != -1); // resize contents if necessary if (contentsLength < contents.length) { System.arraycopy(contents, 0, contents = new char[contentsLength], 0, contentsLength); } } else { contents = new char[length]; int len = 0; int readSize = 0; while ((readSize != -1) && (len != length)) { // See PR 1FMS89U // We record first the read size. In this case len is the actual // read size. len += readSize; readSize = reader.read(contents, len, length - len); } // See PR 1FMS89U // Now we need to resize in case the default encoding used more than // one byte for each // character if (len != length) System.arraycopy(contents, 0, (contents = new char[len]), 0, len); } return contents; } }