/** * Copyright 2009 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS-IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.etherpad.openofficeservice; import net.appjet.common.sars.{SarsServer,SarsMessageHandler}; import java.io.{DataInputStream,DataOutputStream}; import java.io.{File,FileOutputStream,ByteArrayInputStream,ByteArrayOutputStream}; class OOSException(m: String) extends RuntimeException(m); class UnsupportedFormatException(format: String) extends OOSException("Unsupported format: "+format); object TemporaryFailure extends OOSException("Temporary failure"); // stub object here. Please replace if you'd like to use openoffice! object OpenOfficeServerUtility { def checkServerAvailability(host: String, port: Int): Boolean = { return false; } def runOpenOfficeServer(path: String, host: String, port: Int, timeout: Int, wait: Boolean) { // nothing } } class OpenOfficeFileConverter { def setOpenOfficeServerDetails(host: String, port: Int) { // nothing } def convertFile(src: File, dst: File, converter: String, extension: String): Boolean = { return false; } } object OpenOfficeService { val formats = Map( "pdf" -> "writer_pdf_Export", "doc" -> "MS Word 97", "html" -> "HTML (StarWriter)", "odt" -> "writer8", //"html" -> "XHTML Writer File", "txt" -> "Text" ); def createTempFile(bytes: Array[byte], suffix: String) = { var f = File.createTempFile("ooconvert-", if (suffix == null) { null } else if (suffix == "") { "" } else { "."+suffix }); if (bytes != null) { val fos = new FileOutputStream(f); fos.write(bytes); } f; } var soffice = "soffice"; def setExecutable(exec: String) { soffice = exec; } def convertFile(from: String, to: String, bytes: Array[byte]): Array[byte] = { if (from == to) { return bytes; } val tempFile = createTempFile(bytes, from); val outFile = createTempFile(null, to); val openOfficeServerHost = "localhost"; val openOfficeServerPort = 8100; if (! OpenOfficeServerUtility.checkServerAvailability(openOfficeServerHost, openOfficeServerPort)) { try { OpenOfficeServerUtility.runOpenOfficeServer(soffice, openOfficeServerHost, openOfficeServerPort, 20000, true); } catch { case e: java.io.IOException => { e.printStackTrace(); throw TemporaryFailure; } } } var converter = new OpenOfficeFileConverter(); converter.setOpenOfficeServerDetails(openOfficeServerHost, openOfficeServerPort); var status = false; try { status = converter.convertFile(tempFile, outFile, formats(to), to); } catch { case e => { e.printStackTrace(); throw new OOSException("Unknown exception occurred: "+e.getMessage()); } } if (status == false) { throw new UnsupportedFormatException(from); } net.appjet.common.util.BetterFile.getFileBytes(outFile); } def main(args: Array[String]) { if (args.length > 0) { soffice = args(0); if (soffice.length == 0) { exit(1); } } // Query format: // from: String, to: String, count: Int, bytes: Array[byte] // Response format: // status: Int, // status 0 (success) - : count: Int, bytes: Array[byte] // status 1 (temporary failure) - : // status 2 (permanent failure) - : type: Int // type - 0: unknown failure. // - 1: unsupported format val handler = new SarsMessageHandler { override def handle(b: Array[byte]): Option[Array[byte]] = { val is = new DataInputStream(new ByteArrayInputStream(b)); val from = is.readUTF; val to = is.readUTF; val len = is.readInt; val bytes = new Array[byte](len); is.readFully(bytes); var status = 0; var permfailuretype = 0; println("Converting "+from+" -> "+to+" ("+len+" bytes)"); val output = try { convertFile(from, to, bytes); } catch { case TemporaryFailure => { status = 1; null; } case e: UnsupportedFormatException => { status = 2; permfailuretype = 1; null; } case e => { status = 2; permfailuretype = 0; e.printStackTrace(); null; } } val retBytes = new ByteArrayOutputStream(); val ret = new DataOutputStream(retBytes); if (status != 0) { ret.writeInt(status); // error status match { case 2 => { ret.writeInt(permfailuretype); } case _ => { } } } else { ret.writeInt(0); // success ret.writeInt(output.length); ret.write(output, 0, output.length); } Some(retBytes.toByteArray()); } } val server = new SarsServer("ooffice-password", handler, None, 8101); server.start(); println("Server running..."); server.join(); println("Server quitting..."); } }