├── .gitattributes ├── .gitignore ├── src ├── main │ ├── javadoc │ │ ├── org │ │ │ └── fax4j │ │ │ │ └── x2fax │ │ │ │ ├── cli │ │ │ │ └── package.html │ │ │ │ ├── util │ │ │ │ └── package.html │ │ │ │ ├── http │ │ │ │ └── servlet │ │ │ │ │ ├── jetty │ │ │ │ │ └── package.html │ │ │ │ │ └── package.html │ │ │ │ └── email │ │ │ │ └── james │ │ │ │ └── package.html │ │ └── overview.html │ ├── external_files │ │ ├── general │ │ │ ├── configuration │ │ │ │ └── fax4j.properties │ │ │ ├── scripts │ │ │ │ ├── StartUp.bat │ │ │ │ └── StartUp.sh │ │ │ └── test │ │ │ │ └── WindowsTestTool.hta │ │ ├── jetty │ │ │ └── Instructions.txt │ │ ├── war │ │ │ └── Instructions.txt │ │ ├── cli │ │ │ └── Instructions.txt │ │ └── james │ │ │ └── Instructions.txt │ ├── webapp │ │ └── WEB-INF │ │ │ └── web.xml │ ├── java │ │ └── org │ │ │ └── fax4j │ │ │ └── x2fax │ │ │ ├── cli │ │ │ ├── CLI2FaxMain.java │ │ │ └── CLI2FaxRunner.java │ │ │ ├── http │ │ │ └── servlet │ │ │ │ ├── jetty │ │ │ │ └── JettyWeb2FaxMain.java │ │ │ │ ├── Web2FaxHttpServlet.java │ │ │ │ └── AbstractWeb2FaxHttpServlet.java │ │ │ ├── email │ │ │ └── james │ │ │ │ └── EMail2FaxJamesMailet.java │ │ │ └── util │ │ │ └── JavaLauncher.java │ ├── assembly │ │ └── assembly_full.xml │ └── code_inspection │ │ ├── fax4j_checkstyle.xml │ │ └── fax4j_pmd.xml ├── site │ ├── site.xml │ └── xdoc │ │ ├── index.xml │ │ └── setup_instructions.xml ├── test │ └── java │ │ └── org │ │ └── fax4j │ │ └── x2fax │ │ ├── email │ │ └── james │ │ │ └── EMail2FaxJamesMailetTest.java │ │ ├── cli │ │ └── CLI2FaxRunnerTest.java │ │ ├── http │ │ └── servlet │ │ │ └── Web2FaxHttpServletTest.java │ │ └── test │ │ └── TestUtil.java └── changes │ └── changes.xml ├── Docs.html ├── appveyor.yml ├── README.md ├── LICENSE.txt └── pom.xml /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .c9 3 | fax4j-x2fax.iml 4 | target/ 5 | -------------------------------------------------------------------------------- /src/main/javadoc/org/fax4j/x2fax/cli/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Provides standalone CLI utility to send faxes. 4 | 5 | -------------------------------------------------------------------------------- /src/main/external_files/general/configuration/fax4j.properties: -------------------------------------------------------------------------------- 1 | 2 | #The log level, can be DEBUG, INFO, ERROR, NONE 3 | org.fax4j.logger.log.level=NONE 4 | -------------------------------------------------------------------------------- /src/main/javadoc/org/fax4j/x2fax/util/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Provides general utilities used internally by the fax4j x2fax library. 4 | 5 | -------------------------------------------------------------------------------- /src/main/javadoc/org/fax4j/x2fax/http/servlet/jetty/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Provides standalone Jetty HTTP server that provides web2fax services. 4 | 5 | -------------------------------------------------------------------------------- /src/main/javadoc/org/fax4j/x2fax/email/james/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Provides Apache JAMES mailet to extend the JAMES email server and give it email2fax capbilities. 4 | 5 | -------------------------------------------------------------------------------- /src/main/javadoc/org/fax4j/x2fax/http/servlet/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Provides generic servlet which can be deployed on any java web server to provide web2fax service. 4 | 5 | -------------------------------------------------------------------------------- /Docs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ReadMe - fax4j 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/main/external_files/general/scripts/StartUp.bat: -------------------------------------------------------------------------------- 1 | 2 | "%JAVA_HOME%\bin\java.exe" -Dorg.fax4j.x2fax.launcher.class.name=@main.class@ -Dorg.fax4j.x2fax.launcher.jar.dir=@jar.dir@ -cp ./lib/fax4j-x2fax-@project.version@.jar;./lib/fax4j-@fax4j.version@.jar @jvm.args@ org.fax4j.x2fax.util.JavaLauncher %* 3 | -------------------------------------------------------------------------------- /src/main/external_files/general/scripts/StartUp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ${JAVA_HOME}/bin/java -Dorg.fax4j.x2fax.launcher.class.name=@main.class@ -Dorg.fax4j.x2fax.launcher.jar.dir=@jar.dir@ -cp ./lib/fax4j-x2fax-@project.version@.jar:./lib/fax4j-@fax4j.version@.jar @jvm.args@ org.fax4j.x2fax.util.JavaLauncher "$@" 4 | -------------------------------------------------------------------------------- /src/site/site.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/external_files/jetty/Instructions.txt: -------------------------------------------------------------------------------- 1 | 2 | The Jetty HTTP server enables to expose faxing capabilities via HTTP protocol. 3 | 4 | This default parser expects a multi part HTTP request as follows: 5 | -file [file content] 6 | -filename [file name without path] 7 | -priority [priority value as defined in the enum] 8 | -targetaddress [target address] 9 | -targetname [target name] 10 | -sendername [sender name] 11 | -senderfaxnumber [sender fax number] 12 | -senderemail [sender email] 13 | 14 | This may change in case the HTTP request parser was changed via fax4j configuration. 15 | More information on fax4j configuration can be found at: https://sagiegurari.github.io/fax4j/apidocs/overview-summary.html 16 | -------------------------------------------------------------------------------- /src/main/external_files/war/Instructions.txt: -------------------------------------------------------------------------------- 1 | 2 | The Web2Fax.war enables to expose faxing capabilities on top of HTTP web servers. 3 | 4 | This default parser expects a multi part HTTP request as follows: 5 | -file [file content] 6 | -filename [file name without path] 7 | -priority [priority value as defined in the enum] 8 | -targetaddress [target address] 9 | -targetname [target name] 10 | -sendername [sender name] 11 | -senderfaxnumber [sender fax number] 12 | -senderemail [sender email] 13 | 14 | This may change in case the HTTP request parser was changed via fax4j configuration. 15 | More information on fax4j configuration can be found at: https://sagiegurari.github.io/fax4j/apidocs/overview-summary.html 16 | -------------------------------------------------------------------------------- /src/main/external_files/cli/Instructions.txt: -------------------------------------------------------------------------------- 1 | 2 | The SendFax utility enables to send fax based on input parameters. 3 | 4 | The default command line arguments the CLI expects are as follows: 5 | -file [full file name] 6 | -priority [priority value as defined in the enum] 7 | -target_address [target address] 8 | -target_name [target name] 9 | -sender_name [sender name] 10 | -sender_fax_number [sender fax number] 11 | -sender_email [sender email] 12 | -property:[property name] [property value] 13 | 14 | This may change in case the command line arguments parser was changed via fax4j configuration. 15 | More information on fax4j configuration can be found at: https://sagiegurari.github.io/fax4j/apidocs/overview-summary.html 16 | -------------------------------------------------------------------------------- /src/main/javadoc/overview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Overview:

4 | The fax4j x2fax is a set of standalone servers and deployable components which enable to provide x2fax services. 5 | Already comes with built-in email component to enhance email servers to provide email2fax services and HTTP servers and WARs to convert any web server to a web2fax bridge. 6 |
7 | The x2fax is a sub project of the java fax library: fax4j
8 |
9 |

Installation/Setup:

10 | Each server/component has it's installation/setup requirements.
11 | Those installation instructions can be found in each server/component directory.
12 |
13 | @author Sagie Gur-Ari 14 | 15 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Web2Fax 8 | 9 | Simple web application that enables to convert any web server to a web2fax bridge. 10 | 11 | 12 | Web2FaxHttpServlet 13 | org.fax4j.x2fax.http.servlet.Web2FaxHttpServlet 14 | 15 | 16 | Web2FaxHttpServlet 17 | /Web2Fax/* 18 | 19 | -------------------------------------------------------------------------------- /src/main/java/org/fax4j/x2fax/cli/CLI2FaxMain.java: -------------------------------------------------------------------------------- 1 | package org.fax4j.x2fax.cli; 2 | 3 | /** 4 | * This class enables to send faxes via CLI.
5 | * This class does not provide vendor policy capability as it is intended to 6 | * be used internally inside the IT department and not published as a utility to 7 | * end customers. 8 | * 9 | * @author Sagie Gur-Ari 10 | * @version 1.0 11 | * @since 0.01 12 | */ 13 | public final class CLI2FaxMain 14 | { 15 | /** 16 | * This is the class constructor. 17 | */ 18 | private CLI2FaxMain() 19 | { 20 | super(); 21 | } 22 | 23 | /** 24 | * The main method. 25 | * 26 | * @param commandLineArguments 27 | * The command line arguments 28 | */ 29 | public static void main(String[] commandLineArguments) 30 | { 31 | //create runner 32 | CLI2FaxRunner runner=new CLI2FaxRunner(); 33 | runner.initialize(); 34 | 35 | //submit fax 36 | runner.submitFaxJob(commandLineArguments); 37 | 38 | System.exit(0); 39 | } 40 | } -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | 2 | #scripts that run after cloning repository 3 | install: 4 | - cmd: choco install maven -y -f 5 | - cmd: refreshenv 6 | - cmd: SET PATH=C:\maven\apache-maven-3.2.5\bin;%JAVA_HOME%\bin;%PATH% 7 | - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g 8 | - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g 9 | 10 | #to run your custom scripts instead of automatic MSBuild 11 | build_script: 12 | - mvn clean install site 13 | 14 | artifacts: 15 | - path: 'target\fax4j-x2fax-*-full.zip' 16 | 17 | #environment variables 18 | environment: 19 | CI: true 20 | 21 | #branches to build 22 | branches: 23 | #whitelist 24 | only: 25 | - master 26 | - production 27 | 28 | #Do not build on tags (GitHub and BitBucket) 29 | skip_tags: true 30 | 31 | #Maximum number of concurrent jobs for the project 32 | max_jobs: 1 33 | 34 | #Build worker image (VM template) 35 | image: Visual Studio 2015 36 | 37 | #scripts that are called at very beginning, before repo cloning 38 | init: 39 | - git config --global core.autocrlf input 40 | 41 | #fetch repository as zip archive 42 | shallow_clone: false 43 | 44 | matrix: 45 | fast_finish: true 46 | 47 | #build platform, i.e. x86, x64, Any CPU. This setting is optional. 48 | #platform: x86 49 | 50 | #build Configuration, i.e. Debug, Release, etc. 51 | #configuration: Release 52 | -------------------------------------------------------------------------------- /src/main/assembly/assembly_full.xml: -------------------------------------------------------------------------------- 1 | 2 | full 3 | 4 | zip 5 | 6 | true 7 | true 8 | 9 | 10 | ${project.basedir} 11 | 12 | pom.xml 13 | LICENSE.txt 14 | Docs.html 15 | *build* 16 | 17 | 18 | 19 | ${project.basedir}/src 20 | /src 21 | 22 | 23 | ${project.build.directory} 24 | /lib 25 | 26 | ${project.name}-${project.version}.jar 27 | 28 | 29 | 30 | ${project.build.directory}/servers 31 | /servers 32 | 33 | **/* 34 | 35 | 36 | 37 | ${project.build.directory}/components 38 | /components 39 | 40 | **/* 41 | 42 | 43 | 44 | 45 | 46 | /lib 47 | false 48 | false 49 | runtime 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/main/java/org/fax4j/x2fax/http/servlet/jetty/JettyWeb2FaxMain.java: -------------------------------------------------------------------------------- 1 | package org.fax4j.x2fax.http.servlet.jetty; 2 | 3 | import javax.servlet.http.HttpServlet; 4 | import org.eclipse.jetty.server.Server; 5 | import org.eclipse.jetty.servlet.ServletContextHandler; 6 | import org.eclipse.jetty.servlet.ServletHolder; 7 | import org.fax4j.x2fax.http.servlet.Web2FaxHttpServlet; 8 | 9 | /** 10 | * This class starts up a jetty web server to enable to provide 11 | * a web2fax bridge. 12 | * 13 | * @author Sagie Gur-Ari 14 | * @version 1.0 15 | * @since 0.01 16 | */ 17 | public final class JettyWeb2FaxMain 18 | { 19 | /** 20 | * This is the class constructor. 21 | */ 22 | private JettyWeb2FaxMain() 23 | { 24 | super(); 25 | } 26 | 27 | /** 28 | * The main method. 29 | * 30 | * @param commandLineArguments 31 | * The command line arguments 32 | * @throws Exception 33 | * Any exception while setting up and starting the Jetty server 34 | */ 35 | public static void main(String[] commandLineArguments) throws Exception 36 | { 37 | //get port 38 | String value=System.getProperty("fax4j.http.port","80"); 39 | int port=Integer.parseInt(value); 40 | 41 | //create server 42 | Server server=new Server(port); 43 | 44 | ServletContextHandler context=new ServletContextHandler(ServletContextHandler.SESSIONS); 45 | context.setContextPath("/"); 46 | server.setHandler(context); 47 | 48 | //add fax4j servlet 49 | HttpServlet servlet=new Web2FaxHttpServlet(); 50 | context.addServlet(new ServletHolder(servlet),"/Web2Fax/*"); 51 | 52 | server.start(); 53 | server.join(); 54 | } 55 | } -------------------------------------------------------------------------------- /src/test/java/org/fax4j/x2fax/email/james/EMail2FaxJamesMailetTest.java: -------------------------------------------------------------------------------- 1 | package org.fax4j.x2fax.email.james; 2 | 3 | import java.util.Iterator; 4 | import java.util.Properties; 5 | import org.fax4j.FaxClient; 6 | import org.fax4j.bridge.FaxBridge; 7 | import org.fax4j.bridge.email.EMail2FaxBridge; 8 | import org.fax4j.spi.FaxClientSpi; 9 | import org.fax4j.util.ReflectionHelper; 10 | import org.fax4j.x2fax.test.TestUtil; 11 | import org.fax4j.x2fax.test.TestUtil.EmptyFaxClientSpi; 12 | import org.junit.Assert; 13 | import org.junit.Before; 14 | import org.junit.Test; 15 | 16 | /** 17 | * Test Class 18 | * 19 | * @author Sagie Gur-Ari 20 | */ 21 | public class EMail2FaxJamesMailetTest 22 | { 23 | /**The mailet to test*/ 24 | private EMail2FaxJamesMailet mailet; 25 | 26 | /** 27 | * Sets up the test objects. 28 | * 29 | * @throws Exception 30 | * Any exception 31 | */ 32 | @Before 33 | public void setUp() throws Exception 34 | { 35 | this.mailet=new EMail2FaxJamesMailet() 36 | { 37 | @Override 38 | public Iterator getInitParameterNames() 39 | { 40 | Properties configuration=TestUtil.createEmptyFaxClientSpiConfiguration(null); 41 | return configuration.keySet().iterator(); 42 | } 43 | @Override 44 | public String getInitParameter(String key) 45 | { 46 | Properties configuration=TestUtil.createEmptyFaxClientSpiConfiguration(null); 47 | return configuration.getProperty(key); 48 | } 49 | }; 50 | } 51 | 52 | /** 53 | * Test 54 | * 55 | * @throws Exception 56 | * Any exception 57 | */ 58 | @Test 59 | public void initializeTest() throws Exception 60 | { 61 | this.mailet.init(); 62 | FaxBridge faxBridge=this.mailet.flowHelper.getFaxBridge(); 63 | Assert.assertNotNull(faxBridge); 64 | Assert.assertEquals(EMail2FaxBridge.class,faxBridge.getClass()); 65 | FaxClient faxClient=faxBridge.getFaxClient(); 66 | FaxClientSpi faxClientSpi=(FaxClientSpi)ReflectionHelper.getField(FaxClient.class,"FAX_CLIENT_SPI").get(faxClient); 67 | Assert.assertNotNull(faxClientSpi); 68 | Assert.assertEquals(EmptyFaxClientSpi.class,faxClientSpi.getClass()); 69 | } 70 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # x2fax 2 | 3 | [![Build Status](https://ci.appveyor.com/api/projects/status/github/sagiegurari/x2fax?svg=true)](https://ci.appveyor.com/project/sagiegurari/x2fax) [![License](https://img.shields.io/github/license/sagiegurari/x2fax.svg?style=flat)](https://github.com/sagiegurari/x2fax/blob/master/LICENSE.txt) 4 | 5 | > The x2fax (fax4j sub project) is a set of standalone servers and deployable components which enable to provide x2fax capabilities. 6 | 7 | ## Introduction 8 | 9 | The fax4j x2fax is a set of standalone servers and deployable components which enable to provide x2fax services.
10 | Already comes with built-in email component to enhance email servers to provide email2fax services and HTTP servers and WARs to convert any web server to a web2fax bridge.
11 | You can get the latest version from here
12 | The x2fax is a sub project of the fax4j Java faxing library. 13 | 14 | ## Building from Sources 15 | 16 | The fax4j x2fax library comes with a maven pom.xml which can be used to build the library, standalone servers and deployable components. 17 |
18 | While this library supports java 1.5 and up, the build process of this library (not of depended libraries) require java 5/6. 19 |
20 | However building this library from source is not required as it provide many extension capabilities via configuration. 21 | 22 | ## Installation/Setup 23 | 24 | Each server/component has it's installation/setup requirements.
25 | Those installation instructions can be found in each server/component directory.
26 | In addition you can find [here](https://sagiegurari.github.io/x2fax/setup_instructions.html) the instructions and explanation for each server/component. 27 | 28 | ## License 29 | 30 | The fax4j-x2fax library is distributed under the "The Apache Software License, Version 2.0" license which means that it is possible to distribute this library also in commercial closed source products. 31 | 32 | ## Change Log 33 | 34 | See [Change Log](https://sagiegurari.github.io/x2fax/changes-report.html) for full report. 35 | -------------------------------------------------------------------------------- /src/site/xdoc/index.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Overview 5 | 6 | 7 |
8 |

9 | The fax4j x2fax is a set of standalone servers and deployable components which enable to provide x2fax services.
10 | Already comes with built-in email component to enhance email servers to provide email2fax services and HTTP servers and WARs to convert any web server to a web2fax bridge. 11 |
12 | You can get the latest version from here 13 |
14 | The x2fax is a sub project of the fax4j Java faxing library. 15 |

16 |
17 | 18 |
19 |

20 | Please checkout the forums for any questions, comments, bugs, suggestions and so on. 21 |
22 | User testimonials are always welcome. 23 |

24 |
25 | 26 |
27 |

28 | The fax4j x2fax library comes with a maven pom.xml which can be used to build the library, standalone servers and deployable components. 29 |

30 |
31 | 32 |
33 |

34 | Each server/component has it's installation/setup requirements.
35 | Those installation instructions can be found in each server/component directory.
36 | In addition you can find here the instructions and explanation for each server/component. 37 |

38 |
39 | 40 |
41 |

42 | The fax4j-x2fax library is distributed under the "The Apache Software License, Version 2.0" license which means that it is possible to distribute this library also in commercial closed source products.
43 | See license report for more info. 44 |

45 |
46 | 47 |
48 |

49 | See Change Log for full report. 50 |

51 |
52 | 53 |
-------------------------------------------------------------------------------- /src/main/external_files/james/Instructions.txt: -------------------------------------------------------------------------------- 1 | 2 | This bridge component enables to send fax based on recieved mails. 3 | This bridge is meant for installation on apache james email servers. 4 | 5 | Installation Instructions 6 | 1. Install Apache JAMES and validate it works properly 7 | 2. Put all jars from lib directory in /conf/lib 8 | 3. Update the mailet configuration as follows: 9 | 3.1 copy the mailetcontainer-template.conf found in the /conf directory 10 | to same directory with new name: mailetcontainer.conf 11 | 3.2 Create a processor for fax mails as follows 12 | 13 | 14 | 15 | In this example, the fax processor calls the EMail2FaxJamesMailet mailet which is in charge to send the fax. 16 | All mails handled by this processor go through this mailet. 17 | You can than add more mailet for this fax processor to continue handling the mail, for examle you may add 18 | 19 | after the fax mailet to delete the mail. 20 | In similar way you can add custom mailets. 21 | so complete example of processor with both mailets would be: 22 | 23 | 24 | 25 | 26 | 3.3 Create a routing mailet that will route specific mails based on the relevant criteria to the fax processor. 27 | In case of default configuration, the matcher can select only mails that have a subject that starts with fax, 28 | in which case the mailet configuration would be: 29 | 30 | fax 31 | 32 | This configuration needs to be in the root processor. 33 | 34 | The default mail parameters the mailet expects are as follows: 35 | -Subject line: fax:[number] where number is the target address 36 | -From email address would be used as sender email 37 | -First attachment (or in case of none, the body text) would be used as the fax data 38 | 39 | This may change in case the mail parser was changed via fax4j configuration. 40 | More information on fax4j configuration can be found at: https://sagiegurari.github.io/fax4j/apidocs/overview-summary.html 41 | -------------------------------------------------------------------------------- /src/main/java/org/fax4j/x2fax/http/servlet/Web2FaxHttpServlet.java: -------------------------------------------------------------------------------- 1 | package org.fax4j.x2fax.http.servlet; 2 | 3 | import java.io.IOException; 4 | import java.io.Writer; 5 | import javax.servlet.ServletException; 6 | import javax.servlet.http.HttpServletResponse; 7 | import org.fax4j.FaxException; 8 | import org.fax4j.FaxJob; 9 | import org.json.JSONException; 10 | import org.json.JSONObject; 11 | 12 | /** 13 | * This servlet enables to send faxes based on data provided in the HTTP request.
14 | * This class also provides (via VendorPolicy class) the ability to restrict access, bill customers and so on, 15 | * before the fax is submitted. 16 | * 17 | * @author Sagie Gur-Ari 18 | * @version 1.03 19 | * @since 0.01 20 | */ 21 | public class Web2FaxHttpServlet extends AbstractWeb2FaxHttpServlet 22 | { 23 | /**Default UID*/ 24 | private static final long serialVersionUID=1L; 25 | 26 | /** 27 | * This is the class constructor. 28 | */ 29 | public Web2FaxHttpServlet() 30 | { 31 | super(); 32 | } 33 | 34 | /** 35 | * This function writes the response text to the HTTP response stream. 36 | * 37 | * @param faxJob 38 | * The fax job 39 | * @param response 40 | * The HTTP response 41 | * @param writer 42 | * The writer used to write the output to 43 | * @throws ServletException 44 | * If the request for the POST could not be handled 45 | * @throws IOException 46 | * If an input or output error is detected when the servlet handles the request 47 | */ 48 | @Override 49 | protected void writeTextResponse(FaxJob faxJob,HttpServletResponse response,Writer writer) throws ServletException,IOException 50 | { 51 | String text=this.createJSONResponse(faxJob); 52 | writer.write(text); 53 | } 54 | 55 | /** 56 | * This function create a JSON response. 57 | * 58 | * @param faxJob 59 | * The fax job 60 | * @return The JSON string 61 | * @throws ServletException 62 | * If the request for the POST could not be handled 63 | * @throws IOException 64 | * If an input or output error is detected when the servlet handles the request 65 | */ 66 | protected String createJSONResponse(FaxJob faxJob) throws ServletException,IOException 67 | { 68 | //create JSON object with the fax job data 69 | JSONObject jsonObject=new JSONObject(); 70 | try 71 | { 72 | jsonObject.put("FaxJobID",faxJob.getID()); 73 | } 74 | catch(JSONException exception) 75 | { 76 | throw new FaxException("Unable to create JSON response data.",exception); 77 | } 78 | 79 | //convert to string 80 | String jsonString=jsonObject.toString(); 81 | 82 | return jsonString; 83 | } 84 | } -------------------------------------------------------------------------------- /src/test/java/org/fax4j/x2fax/cli/CLI2FaxRunnerTest.java: -------------------------------------------------------------------------------- 1 | package org.fax4j.x2fax.cli; 2 | 3 | import java.io.File; 4 | import java.util.Properties; 5 | import org.fax4j.FaxClient; 6 | import org.fax4j.FaxJob; 7 | import org.fax4j.bridge.FaxBridge; 8 | import org.fax4j.bridge.process.Process2FaxBridge; 9 | import org.fax4j.spi.FaxClientSpi; 10 | import org.fax4j.util.IOHelper; 11 | import org.fax4j.util.ReflectionHelper; 12 | import org.fax4j.x2fax.test.TestUtil; 13 | import org.fax4j.x2fax.test.TestUtil.EmptyFaxClientSpi; 14 | import org.junit.Assert; 15 | import org.junit.Before; 16 | import org.junit.Test; 17 | 18 | /** 19 | * Test Class 20 | * 21 | * @author Sagie Gur-Ari 22 | */ 23 | public class CLI2FaxRunnerTest 24 | { 25 | /**The runner to test*/ 26 | private CLI2FaxRunner runner; 27 | 28 | /** 29 | * Sets up the test objects. 30 | * 31 | * @throws Exception 32 | * Any exception 33 | */ 34 | @Before 35 | public void setUp() throws Exception 36 | { 37 | this.runner=new CLI2FaxRunner() 38 | { 39 | @Override 40 | protected Properties getFaxBridgeConfiguration() 41 | { 42 | return TestUtil.createEmptyFaxClientSpiConfiguration(null); 43 | } 44 | }; 45 | } 46 | 47 | /** 48 | * Test 49 | * 50 | * @throws Exception 51 | * Any exception 52 | */ 53 | @Test 54 | public void initializeTest() throws Exception 55 | { 56 | this.runner.initialize(); 57 | FaxBridge faxBridge=this.runner.flowHelper.getFaxBridge(); 58 | Assert.assertNotNull(faxBridge); 59 | Assert.assertEquals(Process2FaxBridge.class,faxBridge.getClass()); 60 | FaxClient faxClient=faxBridge.getFaxClient(); 61 | FaxClientSpi faxClientSpi=(FaxClientSpi)ReflectionHelper.getField(FaxClient.class,"FAX_CLIENT_SPI").get(faxClient); 62 | Assert.assertNotNull(faxClientSpi); 63 | Assert.assertEquals(EmptyFaxClientSpi.class,faxClientSpi.getClass()); 64 | } 65 | 66 | /** 67 | * Test 68 | * 69 | * @throws Exception 70 | * Any exception 71 | */ 72 | @Test 73 | public void getFaxClientSpiTypeTest() throws Exception 74 | { 75 | String output=this.runner.getFaxClientSpiType(); 76 | Assert.assertNull(output); 77 | } 78 | 79 | /** 80 | * Test 81 | * 82 | * @throws Exception 83 | * Any exception 84 | */ 85 | @Test 86 | public void submitFaxJobTest() throws Exception 87 | { 88 | this.runner.initialize(); 89 | 90 | File file=File.createTempFile("temp_",".txt"); 91 | file.deleteOnExit(); 92 | IOHelper.writeTextFile("abc",file); 93 | 94 | String[] input=new String[]{"-target_address","12345","-file",file.getPath()}; 95 | FaxJob faxJob=this.runner.submitFaxJob(input); 96 | Assert.assertNotNull(faxJob); 97 | Assert.assertNotNull(faxJob.getFile()); 98 | Assert.assertTrue(faxJob.getFile().exists()); 99 | 100 | file.delete(); 101 | } 102 | } -------------------------------------------------------------------------------- /src/test/java/org/fax4j/x2fax/http/servlet/Web2FaxHttpServletTest.java: -------------------------------------------------------------------------------- 1 | package org.fax4j.x2fax.http.servlet; 2 | 3 | import java.util.Enumeration; 4 | import java.util.Iterator; 5 | import java.util.Map.Entry; 6 | import java.util.Properties; 7 | import javax.servlet.ServletConfig; 8 | import org.fax4j.FaxClient; 9 | import org.fax4j.bridge.FaxBridge; 10 | import org.fax4j.bridge.http.HTTP2FaxBridge; 11 | import org.fax4j.spi.FaxClientSpi; 12 | import org.fax4j.util.ReflectionHelper; 13 | import org.fax4j.x2fax.test.TestUtil; 14 | import org.fax4j.x2fax.test.TestUtil.EmptyFaxClientSpi; 15 | import org.junit.Assert; 16 | import org.junit.Before; 17 | import org.junit.Test; 18 | import org.mockito.Mockito; 19 | import org.mockito.stubbing.OngoingStubbing; 20 | 21 | /** 22 | * Test Class 23 | * 24 | * @author Sagie Gur-Ari 25 | */ 26 | public class Web2FaxHttpServletTest 27 | { 28 | /**The servlet to test*/ 29 | private Web2FaxHttpServlet servlet; 30 | 31 | /** 32 | * Sets up the test objects. 33 | * 34 | * @throws Exception 35 | * Any exception 36 | */ 37 | @SuppressWarnings("serial") 38 | @Before 39 | public void setUp() throws Exception 40 | { 41 | this.servlet=new Web2FaxHttpServlet() 42 | { 43 | @SuppressWarnings({"boxing","unchecked"}) 44 | @Override 45 | public ServletConfig getServletConfig() 46 | { 47 | Properties configuration=TestUtil.createEmptyFaxClientSpiConfiguration(null); 48 | 49 | ServletConfig config=Mockito.mock(ServletConfig.class); 50 | Enumeration enumeration=Mockito.mock(Enumeration.class); 51 | OngoingStubbing hasMoreElementsStub=Mockito.when(enumeration.hasMoreElements()); 52 | for(int index=0;index entry=null; 59 | Iterator> iterator=configuration.entrySet().iterator(); 60 | OngoingStubbing nextElementStub=Mockito.when(enumeration.nextElement()); 61 | while(iterator.hasNext()) 62 | { 63 | entry=iterator.next(); 64 | nextElementStub=nextElementStub.thenReturn(entry.getKey()); 65 | Mockito.when(config.getInitParameter((String)entry.getKey())).thenReturn((String)entry.getValue()); 66 | } 67 | 68 | return config; 69 | } 70 | }; 71 | } 72 | 73 | /** 74 | * Test 75 | * 76 | * @throws Exception 77 | * Any exception 78 | */ 79 | @Test 80 | public void initializeTest() throws Exception 81 | { 82 | this.servlet.init(); 83 | FaxBridge faxBridge=this.servlet.flowHelper.getFaxBridge(); 84 | Assert.assertNotNull(faxBridge); 85 | Assert.assertEquals(HTTP2FaxBridge.class,faxBridge.getClass()); 86 | FaxClient faxClient=faxBridge.getFaxClient(); 87 | FaxClientSpi faxClientSpi=(FaxClientSpi)ReflectionHelper.getField(FaxClient.class,"FAX_CLIENT_SPI").get(faxClient); 88 | Assert.assertNotNull(faxClientSpi); 89 | Assert.assertEquals(EmptyFaxClientSpi.class,faxClientSpi.getClass()); 90 | } 91 | } -------------------------------------------------------------------------------- /src/main/java/org/fax4j/x2fax/cli/CLI2FaxRunner.java: -------------------------------------------------------------------------------- 1 | package org.fax4j.x2fax.cli; 2 | 3 | import java.util.Properties; 4 | import org.fax4j.FaxJob; 5 | import org.fax4j.bridge.ContextFaxBridge; 6 | import org.fax4j.bridge.FaxBridgeFlowHelper; 7 | import org.fax4j.bridge.FaxBridgeFlowHelper.FlowResponse; 8 | import org.fax4j.bridge.process.Process2FaxBridge; 9 | 10 | /** 11 | * This class runs the CLI2Fax flow.
12 | * This class does not provide vendor policy capability as it is intended to 13 | * be used internally inside the IT department and not published as a utility to 14 | * end customers. 15 | * 16 | * @author Sagie Gur-Ari 17 | * @version 1.01 18 | * @since 0.01 19 | */ 20 | public class CLI2FaxRunner 21 | { 22 | /**The flow helper*/ 23 | protected FaxBridgeFlowHelper flowHelper; 24 | 25 | /** 26 | * This is the class constructor. 27 | */ 28 | public CLI2FaxRunner() 29 | { 30 | super(); 31 | } 32 | 33 | /** 34 | * This function initializes the runner. 35 | */ 36 | public void initialize() 37 | { 38 | //get configuration 39 | Properties configuration=this.getFaxBridgeConfiguration(); 40 | 41 | //get type 42 | String type=this.getFaxClientSpiType(); 43 | 44 | //create fax bridge 45 | ContextFaxBridge faxBridge=this.createFaxBridge(); 46 | 47 | //create flow helper 48 | this.flowHelper=new FaxBridgeFlowHelper(faxBridge,type,configuration,this); 49 | } 50 | 51 | /** 52 | * This function returns the configuration used to initialize the fax bridge. 53 | * 54 | * @return The configuration used to initialize the fax bridge 55 | */ 56 | protected Properties getFaxBridgeConfiguration() 57 | { 58 | //get configuration 59 | Properties configuration=System.getProperties(); 60 | 61 | return configuration; 62 | } 63 | 64 | /** 65 | * Returns the type of SPI to use. 66 | * 67 | * @return The SPI type 68 | */ 69 | protected String getFaxClientSpiType() 70 | { 71 | return null; 72 | } 73 | 74 | /** 75 | * Returns a new fax bridge. 76 | * 77 | * @return The fax bridge 78 | */ 79 | protected ContextFaxBridge createFaxBridge() 80 | { 81 | return new Process2FaxBridge(); 82 | } 83 | 84 | /** 85 | * This function handles the process output. 86 | * 87 | * @param faxJob 88 | * The fax job 89 | */ 90 | protected void handleOutput(FaxJob faxJob) 91 | { 92 | System.out.println("fax.operation.done=true"); 93 | System.out.println("fax.job.id="+faxJob.getID()); 94 | System.out.println(faxJob); 95 | } 96 | 97 | /** 98 | * Runs the CLI2Fax flow. 99 | * 100 | * @param commandLineArguments 101 | * The command line arguments 102 | * @return The fax job 103 | */ 104 | public FaxJob submitFaxJob(String[] commandLineArguments) 105 | { 106 | //submit fax 107 | FlowResponse flowResponse=this.flowHelper.submitFaxJob(commandLineArguments,commandLineArguments,false); 108 | 109 | //get fax job 110 | FaxJob faxJob=flowResponse.getFaxJob(); 111 | 112 | //handle output 113 | this.handleOutput(faxJob); 114 | 115 | return faxJob; 116 | } 117 | } -------------------------------------------------------------------------------- /src/main/java/org/fax4j/x2fax/email/james/EMail2FaxJamesMailet.java: -------------------------------------------------------------------------------- 1 | package org.fax4j.x2fax.email.james; 2 | 3 | import java.util.Iterator; 4 | import java.util.Properties; 5 | import javax.mail.Message; 6 | import javax.mail.MessagingException; 7 | import org.apache.mailet.Mail; 8 | import org.apache.mailet.base.GenericMailet; 9 | import org.fax4j.FaxJob; 10 | import org.fax4j.bridge.ContextFaxBridge; 11 | import org.fax4j.bridge.FaxBridgeFlowHelper; 12 | import org.fax4j.bridge.FaxBridgeFlowHelper.FlowResponse; 13 | import org.fax4j.bridge.email.EMail2FaxBridge; 14 | 15 | /** 16 | * This servlet enables to send faxes based on data provided in the mail request.
17 | * This class also provides (via VendorPolicy class) the ability to restrict access, bill customers and so on, 18 | * before the fax is submitted. 19 | * 20 | * @author Sagie Gur-Ari 21 | * @version 1.01 22 | * @since 0.01 23 | */ 24 | public class EMail2FaxJamesMailet extends GenericMailet 25 | { 26 | /**The flow helper*/ 27 | protected FaxBridgeFlowHelper flowHelper; 28 | 29 | /** 30 | * This is the class constructor. 31 | */ 32 | public EMail2FaxJamesMailet() 33 | { 34 | super(); 35 | } 36 | 37 | /** 38 | * This function initializes the mailet. 39 | * 40 | * @throws MessagingException 41 | * Any error while initialization 42 | */ 43 | @Override 44 | public void init() throws MessagingException 45 | { 46 | //get configuration 47 | Properties configuration=new Properties(); 48 | Iterator iterator=this.getInitParameterNames(); 49 | String key=null; 50 | String value=null; 51 | while(iterator.hasNext()) 52 | { 53 | //get key/value 54 | key=(String)iterator.next(); 55 | value=this.getInitParameter(key); 56 | 57 | //put in configuration 58 | configuration.setProperty(key,value); 59 | } 60 | 61 | //get type 62 | String type=this.getFaxClientSpiType(); 63 | 64 | //create fax bridge 65 | ContextFaxBridge faxBridge=this.createFaxBridge(); 66 | 67 | //create flow helper 68 | this.flowHelper=new FaxBridgeFlowHelper(faxBridge,type,configuration,this); 69 | } 70 | 71 | /** 72 | * Returns the type of SPI to use. 73 | * 74 | * @return The SPI type 75 | */ 76 | protected String getFaxClientSpiType() 77 | { 78 | return null; 79 | } 80 | 81 | /** 82 | * Returns a new fax bridge. 83 | * 84 | * @return The fax bridge 85 | */ 86 | protected ContextFaxBridge createFaxBridge() 87 | { 88 | return new EMail2FaxBridge(); 89 | } 90 | 91 | /** 92 | * This function is invoked after the fax is submitted. 93 | * 94 | * @param mail 95 | * The mail with the fax data 96 | * @param faxJob 97 | * The submitted fax job 98 | */ 99 | protected void postSubmitFaxJob(Mail mail,FaxJob faxJob) 100 | { 101 | mail.setState(Mail.GHOST); 102 | } 103 | 104 | /** 105 | * This function 106 | * 107 | * @param mail 108 | * The mail with the fax data 109 | * @throws MessagingException 110 | * Any exception while handling the mail message 111 | */ 112 | @Override 113 | public void service(Mail mail) throws MessagingException 114 | { 115 | //get mail message 116 | Message mailMessage=mail.getMessage(); 117 | 118 | //submit fax 119 | FlowResponse flowResponse=this.flowHelper.submitFaxJob(mailMessage,mailMessage,true); 120 | 121 | if(flowResponse.isContinueFlow()) 122 | { 123 | //get fax job 124 | FaxJob faxJob=flowResponse.getFaxJob(); 125 | 126 | //invoke post hook 127 | this.postSubmitFaxJob(mail,faxJob); 128 | } 129 | } 130 | } -------------------------------------------------------------------------------- /src/main/java/org/fax4j/x2fax/util/JavaLauncher.java: -------------------------------------------------------------------------------- 1 | package org.fax4j.x2fax.util; 2 | 3 | import java.io.File; 4 | import java.io.FilenameFilter; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.io.Reader; 8 | import java.util.Arrays; 9 | import java.util.Collections; 10 | import java.util.LinkedList; 11 | import java.util.List; 12 | import org.fax4j.util.IOHelper; 13 | 14 | /** 15 | * Generic launcher for a sub java process. 16 | * 17 | * @author Sagie Gur-Ari 18 | * @version 1.01 19 | * @since 0.01 20 | */ 21 | public final class JavaLauncher 22 | { 23 | /** 24 | * This is the class constructor. 25 | */ 26 | private JavaLauncher() 27 | { 28 | super(); 29 | } 30 | 31 | /** 32 | * The main function that starts the sub process. 33 | * 34 | * @param arguments 35 | * The command line arguments 36 | * @throws IOException 37 | * If unable to start the process 38 | */ 39 | public static void main(String[] arguments) throws IOException 40 | { 41 | if((arguments!=null)&&(arguments.length==1)&&(arguments[0].equals("-help"))) 42 | { 43 | File instructionsFile=new File("./Instructions.txt"); 44 | if(instructionsFile.exists()) 45 | { 46 | String text=IOHelper.readTextFile(instructionsFile); 47 | System.out.println(text); 48 | } 49 | else 50 | { 51 | System.out.println("Help information not available."); 52 | } 53 | } 54 | else //start java process 55 | { 56 | JavaLauncher.invokeJava(arguments); 57 | } 58 | 59 | //exit parent process 60 | System.exit(0); 61 | } 62 | 63 | /** 64 | * This function that starts the java sub process. 65 | * 66 | * @param arguments 67 | * The command line arguments 68 | * @throws IOException 69 | * If unable to start the process 70 | */ 71 | private static void invokeJava(String[] arguments) throws IOException 72 | { 73 | //get main class 74 | String className=System.getProperty("org.fax4j.x2fax.launcher.class.name"); 75 | 76 | //get jar directory path 77 | String jarDirectoryPath=System.getProperty("org.fax4j.x2fax.launcher.jar.dir","./lib"); 78 | File jarDirectory=new File(jarDirectoryPath); 79 | FilenameFilter filter=new FilenameFilter() 80 | { 81 | public boolean accept(File dir,String name) 82 | { 83 | return name.endsWith(".jar"); 84 | } 85 | }; 86 | File[] files=jarDirectory.listFiles(filter); 87 | 88 | StringBuilder buffer=new StringBuilder(); 89 | buffer.append("."); 90 | for(int index=0;index command=new LinkedList(); 103 | command.add(javaExe); 104 | command.add("-cp"); 105 | command.add(classpath); 106 | command.add(className); 107 | if(arguments!=null) 108 | { 109 | Collections.addAll(command,arguments); 110 | } 111 | 112 | //start process 113 | ProcessBuilder processBuilder=new ProcessBuilder(command); 114 | processBuilder.redirectErrorStream(true); 115 | Process process=processBuilder.start(); 116 | InputStream inputStream=process.getInputStream(); 117 | Reader reader=IOHelper.createReader(inputStream,IOHelper.getDefaultEncoding()); 118 | 119 | char[] data=new char[100]; 120 | int read=-1; 121 | try 122 | { 123 | do 124 | { 125 | //read next buffer 126 | read=reader.read(data); 127 | 128 | if(read!=-1) 129 | { 130 | //write to system out 131 | char[] fullData=Arrays.copyOfRange(data,0,read); 132 | System.out.println(new String(fullData)); 133 | } 134 | }while(read!=-1); 135 | } 136 | catch(IOException exception) 137 | { 138 | //ignore 139 | } 140 | 141 | System.out.println("Exit Code: "+process.exitValue()); 142 | } 143 | } -------------------------------------------------------------------------------- /src/main/external_files/general/test/WindowsTestTool.hta: -------------------------------------------------------------------------------- 1 | 2 | 3 | fax4j-x2fax - Tester 4 | 10 | 11 | 52 | 53 | 54 | This is a simple testing tool for the different x2fax bridges.
55 | This tool is very basic and only handles tests based on default fax4j configuration as well as the default directory structure.
56 | This tool is not supported and may be broken with future changes of the x2fax. 57 |
58 | 59 | 60 | 76 | 92 | 93 |
61 |

  Web Tester  

62 | 63 | 64 | 67 | 70 | 73 | 74 |
65 | URL: 66 | 68 | 69 | 71 | 72 |
75 |
77 |

  CLI Tester  

78 | 79 | 80 | 83 | 86 | 89 | 90 |
81 | Dir: 82 | 84 | 85 | 87 | 88 |
91 |
94 |
95 |

Fax Job Data

96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 |
Target Address:
Target Name:
Sender Name:
Sender Fax Number:
Sender EMail:
File Text:
122 |
123 |

Test Output

124 | 125 | 126 | -------------------------------------------------------------------------------- /src/main/code_inspection/fax4j_checkstyle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /src/changes/changes.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | Change Log 7 | Sagie Gur-Ari 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | 33 | 34 | 35 | 36 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | 48 | 49 | 50 | 51 | 52 | 53 | 56 | 57 | 58 | 61 | 62 | 63 | 64 | 65 | 66 | 69 | 70 | 71 | 74 | 75 | 76 | 79 | 80 | 81 | 82 | 83 | 84 | 87 | 88 | 89 | 92 | 93 | 94 | 97 | 98 | 99 | 102 | 103 | 104 | 105 | 106 | 107 | 110 | 111 | 112 | 113 | 114 | 115 | 118 | 119 | 120 | 121 | 122 | 123 | 126 | 127 | 128 | 129 | 130 | 131 | 134 | 135 | 136 | 137 | 138 | 139 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /src/test/java/org/fax4j/x2fax/test/TestUtil.java: -------------------------------------------------------------------------------- 1 | package org.fax4j.x2fax.test; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.Properties; 6 | import java.util.Random; 7 | import org.fax4j.FaxJob; 8 | import org.fax4j.FaxJobStatus; 9 | import org.fax4j.common.LogLevel; 10 | import org.fax4j.common.Logger; 11 | import org.fax4j.common.SimpleLogger; 12 | import org.fax4j.spi.AbstractFax4JClientSpi; 13 | import org.fax4j.spi.FaxClientSpiFactory; 14 | import org.fax4j.spi.FaxJobMonitorImpl; 15 | 16 | /** 17 | * Helper for JUnit test cases. 18 | * 19 | * @author Sagie Gur-Ari 20 | */ 21 | public final class TestUtil 22 | { 23 | /** 24 | * This is the class constructor. 25 | */ 26 | private TestUtil() 27 | { 28 | super(); 29 | } 30 | 31 | /** 32 | * Test method. 33 | * 34 | * @param className 35 | * The SPI class name 36 | * @param configuration 37 | * The configuration 38 | * @return The configuration 39 | */ 40 | public static Properties createFaxClientSpiConfiguration(String className,Properties configuration) 41 | { 42 | Properties updatedConfiguration=configuration; 43 | if(updatedConfiguration==null) 44 | { 45 | updatedConfiguration=new Properties(); 46 | } 47 | updatedConfiguration.setProperty("org.fax4j.proxy.enabled","false"); 48 | updatedConfiguration.setProperty("org.fax4j.spi.type.map.test",className); 49 | updatedConfiguration.setProperty(FaxClientSpiFactory.DEFAULT_SPI_TYPE_PROPERTY_KEY,"test"); 50 | 51 | return updatedConfiguration; 52 | } 53 | 54 | /** 55 | * Test method. 56 | * 57 | * @param configuration 58 | * The configuration 59 | * @return The configuration 60 | */ 61 | public static Properties createEmptyFaxClientSpiConfiguration(Properties configuration) 62 | { 63 | return TestUtil.createFaxClientSpiConfiguration(EmptyFaxClientSpi.class.getName(),configuration); 64 | } 65 | 66 | /** 67 | * Helper class 68 | * 69 | * @author Sagie Gur-Ari 70 | */ 71 | public static class EmptyFaxClientSpi extends AbstractFax4JClientSpi 72 | { 73 | /** 74 | * This is the class constructor. 75 | */ 76 | public EmptyFaxClientSpi() 77 | { 78 | super(); 79 | } 80 | 81 | /** 82 | * This is the class constructor. 83 | * 84 | * @param init 85 | * True to run the init 86 | */ 87 | public EmptyFaxClientSpi(boolean init) 88 | { 89 | this(); 90 | if(init) 91 | { 92 | Logger logger=new SimpleLogger(); 93 | logger.setLogLevel(LogLevel.NONE); 94 | this.initialize(new HashMap(),logger,new FaxJobMonitorImpl()); 95 | } 96 | } 97 | 98 | /** 99 | * Returns the configuration. 100 | * 101 | * @return The configuration 102 | */ 103 | public Map getAllConfiguration() 104 | { 105 | return this.getConfiguration(); 106 | } 107 | 108 | /** 109 | * Empty method. 110 | */ 111 | @Override 112 | protected void initializeImpl() 113 | { 114 | //empty 115 | } 116 | 117 | /** 118 | * This function returns true if the fax monitor events are supported by this SPI. 119 | * 120 | * @return True if the fax monitor events are supported by this SPI 121 | */ 122 | @Override 123 | public boolean isFaxMonitorEventsSupported() 124 | { 125 | return true; 126 | } 127 | 128 | /** 129 | * This function will submit a new fax job.
130 | * The fax job ID may be populated by this method in the provided 131 | * fax job object. 132 | * 133 | * @param faxJob 134 | * The fax job object containing the needed information 135 | */ 136 | @Override 137 | protected void submitFaxJobImpl(FaxJob faxJob) 138 | { 139 | faxJob.setID(String.valueOf((new Random()).nextInt())); 140 | } 141 | 142 | /** 143 | * This function will suspend an existing fax job. 144 | * 145 | * @param faxJob 146 | * The fax job object containing the needed information 147 | */ 148 | @Override 149 | protected void suspendFaxJobImpl(FaxJob faxJob) 150 | { 151 | //empty 152 | } 153 | 154 | /** 155 | * This function will resume an existing fax job. 156 | * 157 | * @param faxJob 158 | * The fax job object containing the needed information 159 | */ 160 | @Override 161 | protected void resumeFaxJobImpl(FaxJob faxJob) 162 | { 163 | //empty 164 | } 165 | 166 | /** 167 | * This function will cancel an existing fax job. 168 | * 169 | * @param faxJob 170 | * The fax job object containing the needed information 171 | */ 172 | @Override 173 | protected void cancelFaxJobImpl(FaxJob faxJob) 174 | { 175 | //empty 176 | } 177 | 178 | /** 179 | * This function returns the fax job status.
180 | * Not all SPIs support extraction of the fax job status.
181 | * In case the SPI is unable to extract or does not support extracting 182 | * of the fax job status, it will return the UNKNOWN status. 183 | * 184 | * @param faxJob 185 | * The fax job object containing the needed information 186 | * @return The fax job status 187 | */ 188 | @Override 189 | protected FaxJobStatus getFaxJobStatusImpl(FaxJob faxJob) 190 | { 191 | String status=faxJob.getProperty("test.status",null); 192 | FaxJobStatus jobStatus=null; 193 | if(status==null) 194 | { 195 | jobStatus=FaxJobStatus.PENDING; 196 | } 197 | else 198 | { 199 | FaxJobStatus lastStatus=FaxJobStatus.valueOf(status); 200 | switch(lastStatus) 201 | { 202 | case PENDING: 203 | jobStatus=FaxJobStatus.IN_PROGRESS; 204 | break; 205 | default: 206 | jobStatus=FaxJobStatus.UNKNOWN; 207 | break; 208 | } 209 | } 210 | status=jobStatus.name(); 211 | faxJob.setProperty("test.status",status); 212 | 213 | return jobStatus; 214 | } 215 | } 216 | } -------------------------------------------------------------------------------- /src/site/xdoc/setup_instructions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Installation/Setup Instructions 5 | 6 | 7 |
8 |

9 | This bridge component enables to send fax based on recieved mails.
10 | This bridge is meant for installation on apache james email servers.
11 |
12 | Installation Instructions
13 | 1. Install Apache JAMES and validate it works properly
14 | 2. Put all jars from lib directory in [Apache JAMES installation directory]/conf/lib
15 | 3. Update the mailet configuration as follows:
16 | 3.1 copy the mailetcontainer-template.conf found in the [Apache JAMES installation directory]/conf directory
17 | to same directory with new name: mailetcontainer.conf
18 | 3.2 Create a processor for fax mails as follows
19 |
20 | <processor state="fax" enableJmx="true">
21 |    <mailet match="All" class="org.fax4j.x2fax.email.james.EMail2FaxJamesMailet"/>
22 | </processor>
23 |
24 | In this example, the fax processor calls the EMail2FaxJamesMailet mailet which is in charge to send the fax.
25 | All mails handled by this processor go through this mailet.
26 | You can than add more mailet for this fax processor to continue handling the mail, for examle you may add
27 | <mailet match="All" class="Null" />
28 | after the fax mailet to delete the mail.
29 | In similar way you can add custom mailets.
30 | so complete example of processor with both mailets would be:
31 |
32 | <processor state="fax" enableJmx="true">
33 |    <mailet match="All" class="org.fax4j.x2fax.email.james.EMail2FaxJamesMailet"/>
34 |    <mailet match="All" class="Null" />
35 | </processor>
36 |
37 | 3.3 Create a routing mailet that will route specific mails based on the relevant criteria to the fax processor.
38 | In case of default configuration, the matcher can select only mails that have a subject that starts with fax,
39 | in which case the mailet configuration would be:
40 |
41 | <mailet match="SubjectStartsWith=fax:" class="ToProcessor">
42 |    <processor>fax</processor>
43 | </mailet>
44 |
45 | This configuration needs to be in the root processor.
46 |
47 | The default mail parameters the mailet expects are as follows:
48 | -Subject line: fax:[number] where number is the target address
49 | -From email address would be used as sender email
50 | -First attachment (or in case of none, the body text) would be used as the fax data
51 |
52 | This may change in case the mail parser was changed via fax4j configuration.
53 | More information on fax4j configuration can be found at: fax4j tutorial
54 |

55 |
56 | 57 |
58 |

59 | The Jetty HTTP server enables to expose faxing capabilities via HTTP protocol.
60 |
61 | This default parser expects a multi part HTTP request as follows:
62 | -file [file content]
63 | -filename [file name without path]
64 | -priority [priority value as defined in the enum]
65 | -targetaddress [target address]
66 | -targetname [target name]
67 | -sendername [sender name]
68 | -senderfaxnumber [sender fax number]
69 | -senderemail [sender email]
70 |
71 | This may change in case the HTTP request parser was changed via fax4j configuration.
72 | More information on fax4j configuration can be found at: fax4j tutorial
73 |

74 |
75 | 76 |
77 |

78 | The Web2Fax.war enables to expose faxing capabilities on top of HTTP web servers.
79 |
80 | This default parser expects a multi part HTTP request as follows:
81 | -file [file content]
82 | -filename [file name without path]
83 | -priority [priority value as defined in the enum]
84 | -targetaddress [target address]
85 | -targetname [target name]
86 | -sendername [sender name]
87 | -senderfaxnumber [sender fax number]
88 | -senderemail [sender email]
89 |
90 | This may change in case the HTTP request parser was changed via fax4j configuration.
91 | More information on fax4j configuration can be found at: fax4j tutorial
92 |

93 |
94 | 95 |
96 |

97 | The SendFax utility enables to send fax based on input parameters.
98 |
99 | The default command line arguments the CLI expects are as follows:
100 | -file [full file name]
101 | -priority [priority value as defined in the enum]
102 | -target_address [target address]
103 | -target_name [target name]
104 | -sender_name [sender name]
105 | -sender_fax_number [sender fax number]
106 | -sender_email [sender email]
107 | -property:[property name] [property value]
108 |
109 | This may change in case the command line arguments parser was changed via fax4j configuration.
110 | More information on fax4j configuration can be found at: fax4j tutorial
111 |

112 |
113 | 114 |
-------------------------------------------------------------------------------- /src/main/java/org/fax4j/x2fax/http/servlet/AbstractWeb2FaxHttpServlet.java: -------------------------------------------------------------------------------- 1 | package org.fax4j.x2fax.http.servlet; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.Writer; 6 | import java.util.Enumeration; 7 | import java.util.Iterator; 8 | import java.util.List; 9 | import java.util.Properties; 10 | import javax.servlet.ServletConfig; 11 | import javax.servlet.ServletException; 12 | import javax.servlet.http.HttpServlet; 13 | import javax.servlet.http.HttpServletRequest; 14 | import javax.servlet.http.HttpServletResponse; 15 | import org.apache.commons.fileupload.FileItem; 16 | import org.apache.commons.fileupload.FileItemFactory; 17 | import org.apache.commons.fileupload.FileUploadException; 18 | import org.apache.commons.fileupload.disk.DiskFileItemFactory; 19 | import org.apache.commons.fileupload.servlet.ServletFileUpload; 20 | import org.fax4j.FaxException; 21 | import org.fax4j.FaxJob; 22 | import org.fax4j.bridge.ContextFaxBridge; 23 | import org.fax4j.bridge.FaxBridgeFlowHelper; 24 | import org.fax4j.bridge.FaxBridgeFlowHelper.FlowResponse; 25 | import org.fax4j.bridge.http.HTTP2FaxBridge; 26 | import org.fax4j.spi.http.HTTPRequest; 27 | import org.fax4j.spi.http.HTTPRequest.ContentPart; 28 | import org.fax4j.spi.http.HTTPRequest.ContentPartType; 29 | import org.fax4j.util.IOHelper; 30 | 31 | /** 32 | * This servlet enables to send faxes based on data provided in the HTTP request.
33 | * This class also provides (via VendorPolicy class) the ability to restrict access, bill customers and so on, 34 | * before the fax is submitted.
35 | * This class does not provide complete implementation of the servlet and requires extending. 36 | * 37 | * @author Sagie Gur-Ari 38 | * @version 1.0 39 | * @since 0.07 40 | */ 41 | public abstract class AbstractWeb2FaxHttpServlet extends HttpServlet 42 | { 43 | /**The flow helper*/ 44 | protected transient FaxBridgeFlowHelper flowHelper; 45 | /**Default UID*/ 46 | private static final long serialVersionUID=1L; 47 | 48 | /** 49 | * This is the class constructor. 50 | */ 51 | public AbstractWeb2FaxHttpServlet() 52 | { 53 | super(); 54 | } 55 | 56 | /** 57 | * This function initializes the servlet. 58 | * 59 | * @throws ServletException 60 | * Any error while initialization 61 | */ 62 | @Override 63 | public void init() throws ServletException 64 | { 65 | //get configuration 66 | Properties configuration=this.getFaxBridgeConfiguration(); 67 | 68 | //get type 69 | String type=this.getFaxClientSpiType(); 70 | 71 | //create fax bridge 72 | ContextFaxBridge faxBridge=this.createFaxBridge(); 73 | 74 | //create flow helper 75 | this.flowHelper=new FaxBridgeFlowHelper(faxBridge,type,configuration,this); 76 | } 77 | 78 | /** 79 | * This function returns the configuration used to initialize the fax bridge. 80 | * 81 | * @return The configuration used to initialize the fax bridge 82 | */ 83 | protected Properties getFaxBridgeConfiguration() 84 | { 85 | //get servlet configuration 86 | ServletConfig servletConfig=this.getServletConfig(); 87 | 88 | //get configuration 89 | Properties configuration=new Properties(); 90 | Enumeration enumeration=servletConfig.getInitParameterNames(); 91 | String key=null; 92 | String value=null; 93 | while(enumeration.hasMoreElements()) 94 | { 95 | //get key/value 96 | key=(String)enumeration.nextElement(); 97 | value=servletConfig.getInitParameter(key); 98 | 99 | //put in configuration 100 | configuration.setProperty(key,value); 101 | } 102 | 103 | return configuration; 104 | } 105 | 106 | /** 107 | * Returns the type of SPI to use. 108 | * 109 | * @return The SPI type 110 | */ 111 | protected String getFaxClientSpiType() 112 | { 113 | return null; 114 | } 115 | 116 | /** 117 | * Returns a new fax bridge. 118 | * 119 | * @return The fax bridge 120 | */ 121 | protected ContextFaxBridge createFaxBridge() 122 | { 123 | return new HTTP2FaxBridge(); 124 | } 125 | 126 | /** 127 | * This function converts the servlet request to a HTTP request object. 128 | * 129 | * @param request 130 | * The servlet request 131 | * @param httpRequest 132 | * The HTTP request to populate 133 | * @throws IOException 134 | * If an input or output error is detected when the servlet handles the request 135 | */ 136 | protected void convertSinglePartRequest(HttpServletRequest request,HTTPRequest httpRequest) throws IOException 137 | { 138 | //get input stream 139 | InputStream inputStream=request.getInputStream(); 140 | 141 | //read data 142 | byte[] content=IOHelper.readStream(inputStream); 143 | 144 | //set content 145 | httpRequest.setContent(content); 146 | } 147 | 148 | /** 149 | * This function creates and returns a new file item factory. 150 | * 151 | * @return The file item factory 152 | */ 153 | protected FileItemFactory createFileItemFactory() 154 | { 155 | FileItemFactory factory=new DiskFileItemFactory(); 156 | return factory; 157 | } 158 | 159 | /** 160 | * This function converts the servlet request to a HTTP request object. 161 | * 162 | * @param request 163 | * The servlet request 164 | * @param httpRequest 165 | * The HTTP request to populate 166 | * @throws IOException 167 | * If an input or output error is detected when the servlet handles the request 168 | */ 169 | protected void convertMultiPartRequest(HttpServletRequest request,HTTPRequest httpRequest) throws IOException 170 | { 171 | ContentPart[] content=null; 172 | try 173 | { 174 | FileItemFactory factory=this.createFileItemFactory(); 175 | ServletFileUpload multiPartRequestHelper=new ServletFileUpload(factory); 176 | List partsList=multiPartRequestHelper.parseRequest(request); 177 | 178 | //init content array 179 | content=new ContentPart[partsList.size()]; 180 | 181 | Iterator iterator=partsList.iterator(); 182 | FileItem fileItem=null; 183 | int index=0; 184 | String name=null; 185 | byte[] data=null; 186 | while(iterator.hasNext()) 187 | { 188 | //get next item 189 | fileItem=iterator.next(); 190 | 191 | //add to parts list 192 | name=fileItem.getFieldName(); 193 | data=fileItem.get(); 194 | content[index]=new ContentPart(name,data,ContentPartType.BINARY); 195 | 196 | //advance index 197 | index++; 198 | } 199 | } 200 | catch(FileUploadException exception) 201 | { 202 | throw new FaxException("Unable to part multi part request.",exception); 203 | } 204 | 205 | //set content 206 | httpRequest.setContent(content); 207 | } 208 | 209 | /** 210 | * This function converts the servlet request to a HTTP request object. 211 | * 212 | * @param request 213 | * The servlet request 214 | * @return The HTTP request 215 | * @throws IOException 216 | * If an input or output error is detected when the servlet handles the request 217 | */ 218 | protected HTTPRequest convertRequest(HttpServletRequest request) throws IOException 219 | { 220 | //init request 221 | HTTPRequest httpRequest=new HTTPRequest(); 222 | 223 | //read content 224 | int length=request.getContentLength(); 225 | if(length>0) 226 | { 227 | boolean multiPartRequest=ServletFileUpload.isMultipartContent(request); 228 | if(multiPartRequest) 229 | { 230 | this.convertMultiPartRequest(request,httpRequest); 231 | } 232 | else 233 | { 234 | this.convertSinglePartRequest(request,httpRequest); 235 | } 236 | } 237 | 238 | //set values 239 | httpRequest.setResource(request.getContextPath()); 240 | httpRequest.setParametersText(request.getQueryString()); 241 | 242 | return httpRequest; 243 | } 244 | 245 | /** 246 | * This function sends the HTTP response after sending the fax. 247 | * 248 | * @param faxJob 249 | * The fax job 250 | * @param response 251 | * The HTTP response 252 | * @throws ServletException 253 | * If the request for the POST could not be handled 254 | * @throws IOException 255 | * If an input or output error is detected when the servlet handles the request 256 | */ 257 | protected void sendResponse(FaxJob faxJob,HttpServletResponse response) throws ServletException,IOException 258 | { 259 | //set status 260 | response.setStatus(HttpServletResponse.SC_OK); 261 | 262 | //set response content type 263 | response.setContentType("text/plain"); 264 | 265 | //get writer 266 | Writer writer=response.getWriter(); 267 | 268 | //write fax job details 269 | this.writeTextResponse(faxJob,response,writer); 270 | 271 | //commit response 272 | response.flushBuffer(); 273 | } 274 | 275 | /** 276 | * This function handles the HTTP request and submits the fax. 277 | * 278 | * @param request 279 | * The HTTP request 280 | * @param response 281 | * The HTTP response 282 | * @throws ServletException 283 | * If the request for the POST could not be handled 284 | * @throws IOException 285 | * If an input or output error is detected when the servlet handles the request 286 | */ 287 | @Override 288 | protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException 289 | { 290 | //create request data holder 291 | RequestDataHolder requestDataHolder=new RequestDataHolder(request,response); 292 | 293 | //convert request 294 | HTTPRequest httpRequest=this.convertRequest(request); 295 | 296 | //submit fax 297 | FlowResponse flowResponse=this.flowHelper.submitFaxJob(httpRequest,requestDataHolder,true); 298 | 299 | if(flowResponse.isContinueFlow()) 300 | { 301 | //get fax job 302 | FaxJob faxJob=flowResponse.getFaxJob(); 303 | 304 | //send response 305 | this.sendResponse(faxJob,response); 306 | } 307 | } 308 | 309 | /** 310 | * This function writes the response text to the HTTP response stream. 311 | * 312 | * @param faxJob 313 | * The fax job 314 | * @param response 315 | * The HTTP response 316 | * @param writer 317 | * The writer used to write the output to 318 | * @throws ServletException 319 | * If the request for the POST could not be handled 320 | * @throws IOException 321 | * If an input or output error is detected when the servlet handles the request 322 | */ 323 | protected abstract void writeTextResponse(FaxJob faxJob,HttpServletResponse response,Writer writer) throws ServletException,IOException; 324 | 325 | /** 326 | * Holds the request data for the vendor policy. 327 | * 328 | * @author Sagie Gur-Ari 329 | * @version 1.0 330 | * @since 0.01 331 | */ 332 | public static class RequestDataHolder 333 | { 334 | /**The HTTP request*/ 335 | private final HttpServletRequest REQUEST; 336 | /**The HTTP response*/ 337 | private final HttpServletResponse RESPONSE; 338 | 339 | /** 340 | * This is the class constructor. 341 | * 342 | * @param request 343 | * The HTTP request 344 | * @param response 345 | * The HTTP response 346 | */ 347 | public RequestDataHolder(HttpServletRequest request,HttpServletResponse response) 348 | { 349 | super(); 350 | 351 | this.REQUEST=request; 352 | this.RESPONSE=response; 353 | } 354 | 355 | /** 356 | * Returns the http request. 357 | * 358 | * @return The http request 359 | */ 360 | public HttpServletRequest getHttpServletRequest() 361 | { 362 | return this.REQUEST; 363 | } 364 | 365 | /** 366 | * Returns the http response. 367 | * 368 | * @return The http response 369 | */ 370 | public HttpServletResponse getHttpServletResponse() 371 | { 372 | return this.RESPONSE; 373 | } 374 | } 375 | } -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/main/code_inspection/fax4j_pmd.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | fax4j PMD rule set 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 4.0.0 6 | 7 | net.sf.fax4j 8 | fax4j-x2fax 9 | 0.1.3 10 | jar 11 | 12 | 13 | UTF-8 14 | 0.43.5 15 | 16 | 17 | fax4j-x2fax 18 | 19 | The fax4j x2fax is a set of standalone servers and deployable components which enable to provide x2fax services. 20 | Already comes with built-in email component to enhance email servers to provide email2fax services and HTTP servers and WARs to convert any web server to a web2fax bridge. 21 | 22 | https://github.com/sagiegurari/x2fax 23 | 24 | ${project.name} 25 | https://github.com/sagiegurari/x2fax 26 | 27 | 2013 28 | 29 | 30 | sagiegurari 31 | Sagie Gur-Ari 32 | sagiegurari@gmail.com 33 | 34 | Project Author 35 | 36 | 37 | 38 | 39 | ${project.name} forums 40 | https://github.com/sagiegurari/x2fax/issues 41 | 42 | 43 | 44 | 45 | The Apache Software License, Version 2.0 46 | http://www.apache.org/licenses/LICENSE-2.0.txt 47 | repo 48 | 49 | The fax4j-x2fax and fax4j libraries are distributed under the "The Apache Software License, Version 2.0" license which means that it is possible to distribute these libraries also in commercial closed source products. 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | net.sf.fax4j 58 | fax4j 59 | ${fax4j.version} 60 | 61 | 62 | org.eclipse.jetty 63 | jetty-server 64 | 7.6.0.RC5 65 | 66 | 67 | org.eclipse.jetty 68 | jetty-servlet 69 | 7.6.0.RC5 70 | 71 | 72 | commons-fileupload 73 | commons-fileupload 74 | 1.3 75 | 76 | 77 | org.apache.james 78 | james-server-mailets 79 | 3.0-M2 80 | provided 81 | 82 | 83 | 84 | 85 | junit 86 | junit 87 | 4.8.2 88 | test 89 | 90 | 91 | org.powermock 92 | powermock-module-junit4 93 | 1.5.1 94 | test 95 | 96 | 97 | org.powermock 98 | powermock-api-mockito 99 | 1.5.1 100 | test 101 | 102 | 103 | 104 | 105 | 106 | 107 | org.apache.maven.plugins 108 | maven-compiler-plugin 109 | 2.3.2 110 | 111 | 1.5 112 | 113 | 114 | 115 | org.apache.maven.plugins 116 | maven-jar-plugin 117 | 2.3.2 118 | 119 | 120 | 121 | true 122 | true 123 | 124 | 125 | ${project.name} 126 | 127 | 128 | 129 | 130 | 131 | org.apache.maven.plugins 132 | maven-source-plugin 133 | 2.2.1 134 | 135 | 136 | attach-sources 137 | verify 138 | 139 | jar-no-fork 140 | 141 | 142 | 143 | 144 | 145 | org.apache.maven.plugins 146 | maven-javadoc-plugin 147 | 2.9.1 148 | 149 | 150 | attach-javadocs 151 | 152 | jar 153 | 154 | 155 | 156 | 157 | 158 | org.apache.maven.plugins 159 | maven-assembly-plugin 160 | 2.4 161 | 162 | ${project.basedir}/src/main/assembly/assembly_full.xml 163 | 164 | 165 | 166 | site 167 | 168 | single 169 | 170 | 171 | 172 | 173 | 174 | org.apache.maven.plugins 175 | maven-site-plugin 176 | 3.3 177 | 178 | true 179 | 180 | 181 | 182 | org.codehaus.mojo 183 | license-maven-plugin 184 | 1.5 185 | 186 | 187 | update-project-license 188 | 189 | update-project-license 190 | 191 | 192 | apache_v2 193 | true 194 | UTF-8 195 | 196 | 197 | 198 | add-third-party 199 | 200 | add-third-party 201 | 202 | 203 | test 204 | 205 | The Apache Software License, Version 2.0|Apache 2|Apache License 2.0|Apache License|Apache License, Version 2.0 206 | 207 | 208 | 209 | 210 | 211 | 212 | org.apache.maven.plugins 213 | maven-antrun-plugin 214 | 1.7 215 | 216 | 217 | com.sun 218 | tools 219 | 1.5.0 220 | system 221 | ${java.home}/../lib/tools.jar 222 | 223 | 224 | 225 | 226 | construct-components 227 | verify 228 | 229 | 230 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | run 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | org.apache.maven.plugins 341 | maven-project-info-reports-plugin 342 | 2.7 343 | 344 | 345 | 346 | index 347 | license 348 | summary 349 | issue-tracking 350 | scm 351 | project-team 352 | dependencies 353 | dependency-info 354 | plugin-management 355 | plugins 356 | dependency-management 357 | help 358 | 359 | 360 | 361 | 362 | 363 | org.apache.maven.plugins 364 | maven-changes-plugin 365 | 2.9 366 | 367 | 368 | 369 | changes-report 370 | 371 | 372 | 373 | 374 | false 375 | 376 | 377 | 378 | org.apache.maven.plugins 379 | maven-surefire-report-plugin 380 | 2.15 381 | 382 | 383 | org.apache.maven.plugins 384 | maven-javadoc-plugin 385 | 2.9.1 386 | 387 | 388 | org.apache.maven.plugins 389 | maven-jxr-plugin 390 | 2.3 391 | 392 | 393 | org.apache.maven.plugins 394 | maven-pmd-plugin 395 | 3.0.1 396 | 397 | 75 398 | 399 | ${project.basedir}/src/main/code_inspection/fax4j_pmd.xml 400 | 401 | 402 | 403 | 404 | org.apache.maven.plugins 405 | maven-checkstyle-plugin 406 | 2.10 407 | 408 | ${project.basedir}/src/main/code_inspection/fax4j_checkstyle.xml 409 | 410 | 411 | 412 | org.codehaus.mojo 413 | cobertura-maven-plugin 414 | 2.5.2 415 | 416 | 417 | org.codehaus.mojo 418 | taglist-maven-plugin 419 | 2.4 420 | 421 | 422 | 423 | 424 | TODOs 425 | 426 | 427 | TODO 428 | ignoreCase 429 | 430 | 431 | FIXME 432 | ignoreCase 433 | 434 | 435 | 436 | 437 | Deprecated 438 | 439 | 440 | deprecated 441 | ignoreCase 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | org.codehaus.mojo 451 | clirr-maven-plugin 452 | 2.6.1 453 | 454 | info 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | Release_Profile 463 | 464 | 465 | env.FAX4J_GPG_PASSPHRASE 466 | 467 | 468 | 469 | 470 | 471 | org.apache.maven.plugins 472 | maven-gpg-plugin 473 | 1.4 474 | 475 | 476 | sign-artifacts 477 | verify 478 | 479 | sign 480 | 481 | 482 | ${env.FAX4J_GPG_PASSPHRASE} 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | --------------------------------------------------------------------------------