librepdf 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,231 @@
1
+
2
+ package librepdf;
3
+
4
+ import librepdf.document.Factory;
5
+ import librepdf.document.Document;
6
+
7
+ import java.io.Closeable;
8
+ import java.io.IOException;
9
+ import java.util.Map;
10
+ import java.util.HashMap;
11
+ import java.net.ConnectException;
12
+ import org.jruby.*;
13
+ import org.jruby.runtime.ThreadContext;
14
+ import org.jruby.runtime.builtin.IRubyObject;
15
+ import org.jruby.javasupport.JavaEmbedUtils;
16
+
17
+ import com.sun.star.beans.XPropertySet;
18
+ import com.sun.star.beans.PropertyValue;
19
+ import com.sun.star.bridge.XBridge;
20
+ import com.sun.star.bridge.XBridgeFactory;
21
+ import com.sun.star.comp.helper.Bootstrap;
22
+ import com.sun.star.connection.NoConnectException;
23
+ import com.sun.star.connection.XConnection;
24
+ import com.sun.star.connection.XConnector;
25
+ import com.sun.star.frame.XComponentLoader;
26
+ import com.sun.star.frame.XStorable;
27
+ import com.sun.star.lang.EventObject;
28
+ import com.sun.star.lang.XComponent;
29
+ import com.sun.star.lang.XEventListener;
30
+ import com.sun.star.lang.XMultiComponentFactory;
31
+ import com.sun.star.task.ErrorCodeIOException;
32
+ import com.sun.star.uno.UnoRuntime;
33
+ import com.sun.star.uno.XComponentContext;
34
+
35
+ public final class Connection implements Closeable, Finalizable
36
+ {
37
+ public static String DEFAULT_HOST = "127.0.0.1";
38
+ public static int DEFAULT_PORT = 8100;
39
+
40
+ private final Ruby runtime;
41
+ private final String host;
42
+ private final int port;
43
+
44
+ private boolean closed = false;
45
+
46
+ private XComponent bridgeComponent;
47
+ private XComponentContext componentContext;
48
+ private XMultiComponentFactory serviceManager;
49
+
50
+ public Connection() throws ConnectException {
51
+ this(new HashMap<String, Object>(), null);
52
+ }
53
+
54
+ public Connection(RubyProc proc) throws ConnectException {
55
+ this(new HashMap<String, Object>(), proc);
56
+ }
57
+
58
+ public Connection(Map<String, Object> options) throws ConnectException {
59
+ this(options, null);
60
+ }
61
+
62
+ public Connection(Map<String, Object> options, RubyProc proc) throws ConnectException {
63
+ this.runtime = Ruby.getGlobalRuntime();
64
+ this.runtime.addInternalFinalizer(this);
65
+
66
+ if (options.containsKey("host")) {
67
+ this.host = options.get("host").toString();
68
+ } else {
69
+ this.host = DEFAULT_HOST;
70
+ }
71
+ if (options.containsKey("port")) {
72
+ final Object p = options.get("port");
73
+ if (!(p instanceof Long)) {
74
+ throw new IllegalArgumentException("The port required the number between 0-65535.");
75
+ }
76
+
77
+ final Long l = (Long)p;
78
+ if (!(0 < l && l < 65536)) {
79
+ throw new IllegalArgumentException("The port required the number between 0-65535.");
80
+ }
81
+ this.port = l.intValue();
82
+ } else {
83
+ this.port = DEFAULT_PORT;
84
+ }
85
+
86
+ this.open();
87
+ if (proc != null) {
88
+ try {
89
+ final ThreadContext context = this.runtime.getCurrentContext();
90
+ final IRubyObject[] args = { JavaEmbedUtils.javaToRuby(this.runtime, this) };
91
+ proc.call(context, args);
92
+ } finally {
93
+ try {
94
+ this.close();
95
+ } catch (Exception e) {
96
+ }
97
+ }
98
+ }
99
+ }
100
+
101
+ @Override
102
+ public void finalize() throws Throwable {
103
+ try {
104
+ this.close();
105
+ } catch(IOException e) {}
106
+ }
107
+
108
+ @Override
109
+ public synchronized void close() throws IOException {
110
+ if (!this.closed) {
111
+ this.bridgeComponent.dispose();
112
+ this.runtime.removeInternalFinalizer(this);
113
+ this.closed = true;
114
+ }
115
+ }
116
+
117
+ @Override
118
+ public String toString() {
119
+ return "#<Librepdf::Connection host=" + this.host + ",port=" + this.port + ">";
120
+ }
121
+
122
+ public boolean isClosed() {
123
+ return this.closed;
124
+ }
125
+
126
+ public String inspect() {
127
+ return this.toString();
128
+ }
129
+
130
+ private synchronized void open() throws ConnectException {
131
+ final String connectionString = "socket,host=" + this.host + ",port=" + this.port + ",tcpNoDelay=1";
132
+
133
+ try {
134
+ final XComponentContext localContext = Bootstrap.createInitialComponentContext(null);
135
+ final XMultiComponentFactory localServiceManager = localContext.getServiceManager();
136
+ final XConnector connector = (XConnector) UnoRuntime.queryInterface(XConnector.class, localServiceManager
137
+ .createInstanceWithContext("com.sun.star.connection.Connector", localContext));
138
+ final XConnection connection = connector.connect(connectionString);
139
+ final XBridgeFactory bridgeFactory = (XBridgeFactory) UnoRuntime.queryInterface(XBridgeFactory.class,
140
+ localServiceManager.createInstanceWithContext("com.sun.star.bridge.BridgeFactory", localContext));
141
+ final XBridge bridge = bridgeFactory.createBridge("", "urp", connection, null);
142
+
143
+ this.bridgeComponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, bridge);
144
+ this.serviceManager = (XMultiComponentFactory) UnoRuntime.queryInterface(XMultiComponentFactory.class,
145
+ bridge.getInstance("StarOffice.ServiceManager"));
146
+
147
+ final XPropertySet properties = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,
148
+ this.serviceManager);
149
+ this.componentContext = (XComponentContext) UnoRuntime.queryInterface(XComponentContext.class, properties
150
+ .getPropertyValue("DefaultContext"));
151
+
152
+ } catch (Exception e) {
153
+ throw new ConnectException("connection failed: " + connectionString + ": " + e.getMessage());
154
+ }
155
+ }
156
+
157
+ public Document load(String inputUrl) {
158
+ return this.load(inputUrl, new HashMap<String, Object>());
159
+ }
160
+
161
+ public Document load(String inputUrl, Map<String, Object> options) {
162
+ if (inputUrl == null) {
163
+ throw new IllegalArgumentException("Null connot be set for inputUrl.");
164
+ }
165
+ if (this.closed) {
166
+ throw new IllegalArgumentException("The connection has not established it.");
167
+ }
168
+
169
+ options.put("Hidden", true);
170
+ options.put("ReadOnly", true);
171
+ final PropertyValue[] inputProperties = Utils.toPropertyValues(options);
172
+
173
+ final XComponent document = this.loadInternal(inputUrl, inputProperties);
174
+
175
+ return Factory.factory(this, this.runtime, document);
176
+ }
177
+
178
+ public Document load(String inputUrl, RubyProc proc) {
179
+ return this.load(inputUrl, new HashMap<String, Object>(), proc);
180
+ }
181
+
182
+ public Document load(String inputUrl, Map<String, Object> options, RubyProc proc) {
183
+ if (inputUrl == null) {
184
+ throw new IllegalArgumentException("Null connot be set for inputUrl.");
185
+ }
186
+ if (this.closed) {
187
+ throw new IllegalArgumentException("The connection has not established it.");
188
+ }
189
+
190
+ options.put("Hidden", true);
191
+ options.put("ReadOnly", true);
192
+ final PropertyValue[] inputProperties = Utils.toPropertyValues(options);
193
+
194
+ final XComponent document = this.loadInternal(inputUrl, inputProperties);
195
+
196
+ return Factory.factory(this, this.runtime, document, proc);
197
+ }
198
+
199
+ private XComponentLoader getDesktop() {
200
+ return (XComponentLoader) UnoRuntime.queryInterface(XComponentLoader.class,
201
+ this.getService("com.sun.star.frame.Desktop"));
202
+ }
203
+
204
+ private Object getService(String className) {
205
+ if (className == null) {
206
+ throw new IllegalArgumentException("Null connot be set for className.");
207
+ }
208
+
209
+ try {
210
+ return this.serviceManager.createInstanceWithContext(className, this.componentContext);
211
+
212
+ } catch (Exception e) {
213
+ throw new RuntimeException("could not obtain service: " + className, e);
214
+ }
215
+ }
216
+
217
+ private XComponent loadInternal(String inputUrl, PropertyValue[] properties) {
218
+ final XComponentLoader desktop = this.getDesktop();
219
+ try {
220
+ return desktop.loadComponentFromURL(inputUrl, "_blank", 0, properties);
221
+
222
+ } catch (ErrorCodeIOException e) {
223
+ throw new RuntimeException("could not load input document. " + e.ErrCode, e);
224
+
225
+ } catch (Exception e) {
226
+ throw new RuntimeException("could not load input document.", e);
227
+
228
+ }
229
+ }
230
+ }
231
+
@@ -0,0 +1,29 @@
1
+
2
+ package librepdf;
3
+
4
+ import java.util.Map;
5
+ import java.util.Iterator;
6
+ import com.sun.star.beans.PropertyValue;
7
+
8
+ public final class Utils
9
+ {
10
+ public static PropertyValue[] toPropertyValues(Map properties) {
11
+ final PropertyValue[] ret = new PropertyValue[properties.size()];
12
+ int i = 0;
13
+ for (Iterator it = properties.entrySet().iterator(); it.hasNext();) {
14
+ Map.Entry entry = (Map.Entry)it.next();
15
+ String key = entry.getKey().toString();
16
+ Object val = entry.getValue();
17
+
18
+ ret[i] = new PropertyValue();
19
+ ret[i].Name = key;
20
+ ret[i].Value = (val instanceof Map) ? Utils.toPropertyValues((Map)val) : val;
21
+
22
+ i++;
23
+ }
24
+ return ret;
25
+ }
26
+
27
+ private Utils() {}
28
+ }
29
+
@@ -0,0 +1,25 @@
1
+
2
+ package librepdf.document;
3
+
4
+ import librepdf.Connection;
5
+ import java.util.Map;
6
+ import org.jruby.Ruby;
7
+ import org.jruby.RubyProc;
8
+ import com.sun.star.lang.XComponent;
9
+
10
+ class Calc extends Document
11
+ {
12
+ Calc(Connection connection, Ruby runtime, XComponent document) {
13
+ super(connection, runtime, document);
14
+ }
15
+
16
+ Calc(Connection connection, Ruby runtime, XComponent document, RubyProc proc) {
17
+ super(connection, runtime, document, proc);
18
+ }
19
+
20
+ @Override
21
+ protected void setDefaultOptions(Map<String, Object> options) {
22
+ options.put("FilterName", "calc_pdf_Export");
23
+ }
24
+ }
25
+
@@ -0,0 +1,25 @@
1
+
2
+ package librepdf.document;
3
+
4
+ import librepdf.Connection;
5
+ import java.util.Map;
6
+ import org.jruby.Ruby;
7
+ import org.jruby.RubyProc;
8
+ import com.sun.star.lang.XComponent;
9
+
10
+ class Chart extends Document
11
+ {
12
+ Chart(Connection connection, Ruby runtime, XComponent document) {
13
+ super(connection, runtime, document);
14
+ }
15
+
16
+ Chart(Connection connection, Ruby runtime, XComponent document, RubyProc proc) {
17
+ super(connection, runtime, document, proc);
18
+ }
19
+
20
+ @Override
21
+ protected void setDefaultOptions(Map<String, Object> options) {
22
+ options.put("FilterName", "chart_pdf_Export");
23
+ }
24
+ }
25
+
@@ -0,0 +1,124 @@
1
+
2
+ package librepdf.document;
3
+
4
+ import librepdf.Connection;
5
+ import librepdf.Utils;
6
+
7
+ import java.util.Map;
8
+ import java.util.HashMap;
9
+ import java.io.Closeable;
10
+ import java.io.IOException;
11
+ import org.jruby.*;
12
+ import org.jruby.runtime.ThreadContext;
13
+ import org.jruby.runtime.builtin.IRubyObject;
14
+ import org.jruby.javasupport.JavaEmbedUtils;
15
+
16
+ import com.sun.star.beans.PropertyValue;
17
+ import com.sun.star.frame.XStorable;
18
+ import com.sun.star.util.XCloseable;
19
+ import com.sun.star.util.CloseVetoException;
20
+ import com.sun.star.task.ErrorCodeIOException;
21
+ import com.sun.star.lang.XComponent;
22
+ import com.sun.star.lang.XServiceInfo;
23
+ import com.sun.star.uno.UnoRuntime;
24
+
25
+ public abstract class Document implements Closeable, Finalizable
26
+ {
27
+ private final Connection connection;
28
+ private final Ruby runtime;
29
+ private final XComponent document;
30
+
31
+ private boolean closed = false;
32
+
33
+ Document(Connection connection, Ruby runtime, XComponent document) {
34
+ this.connection = connection;
35
+ this.runtime = runtime;
36
+ this.document = document;
37
+ this.runtime.addInternalFinalizer(this);
38
+ }
39
+
40
+ Document(Connection connection, Ruby runtime, XComponent document, RubyProc proc) {
41
+ this(connection, runtime, document);
42
+
43
+ final ThreadContext context = this.runtime.getCurrentContext();
44
+ final IRubyObject[] args = { JavaEmbedUtils.javaToRuby(this.runtime, this) };
45
+
46
+ try {
47
+ proc.call(context, args);
48
+ } finally {
49
+ try {
50
+ this.close();
51
+ } catch (Exception e) {
52
+ }
53
+ }
54
+ }
55
+
56
+ @Override
57
+ public void finalize() throws Throwable {
58
+ try {
59
+ close();
60
+ } catch (IOException e) {}
61
+ }
62
+
63
+ @Override
64
+ public void close() throws IOException {
65
+ if (!this.closed) {
66
+ final XCloseable closeable = (XCloseable) UnoRuntime.queryInterface(XCloseable.class, document);
67
+ try {
68
+ closeable.close(false);
69
+ } catch (CloseVetoException e) {
70
+ throw new IOException("chould not close document.", e);
71
+ }
72
+ this.runtime.removeInternalFinalizer(this);
73
+ this.closed = true;
74
+ }
75
+ }
76
+
77
+ public void convertPdf(String outputUrl) {
78
+ this.convertPdf(outputUrl, new HashMap<String, Object>());
79
+ }
80
+
81
+ public void convertPdf(String outputUrl, Map<String, Object> options) {
82
+ if (outputUrl == null) {
83
+ throw new IllegalArgumentException("Null connot be set for outputUrl.");
84
+ }
85
+ if (this.connection.isClosed()) {
86
+ throw new IllegalArgumentException("The connection has not established it.");
87
+ }
88
+
89
+ final XStorable storable = (XStorable) UnoRuntime.queryInterface(XStorable.class, document);
90
+
91
+ if (!options.containsKey("FilterData")) options.put("FilterData", new HashMap<String, Object>());
92
+ this.setDefaultOptions(options);
93
+ final PropertyValue[] outputProperties = Utils.toPropertyValues(options);
94
+
95
+ try {
96
+ storable.storeToURL(outputUrl, outputProperties);
97
+
98
+ } catch (ErrorCodeIOException e) {
99
+ throw new RuntimeException("could not save output document. " + e.ErrCode, e);
100
+
101
+ } catch (Exception e) {
102
+ throw new RuntimeException("could not save output document", e);
103
+
104
+ }
105
+ }
106
+
107
+ @Override
108
+ public String toString() {
109
+ return "#<Librepdf::Document::" + this.getClass().getSimpleName() + ">";
110
+ }
111
+
112
+ public boolean isClosed() {
113
+ return this.closed;
114
+ }
115
+
116
+ public String inspect() {
117
+ return this.toString();
118
+ }
119
+
120
+ protected void setDefaultOptions(Map<String, Object> options) {
121
+ // do nothing.
122
+ }
123
+ }
124
+
@@ -0,0 +1,25 @@
1
+
2
+ package librepdf.document;
3
+
4
+ import librepdf.Connection;
5
+ import java.util.Map;
6
+ import org.jruby.Ruby;
7
+ import org.jruby.RubyProc;
8
+ import com.sun.star.lang.XComponent;
9
+
10
+ class Draw extends Document
11
+ {
12
+ Draw(Connection connection, Ruby runtime, XComponent document) {
13
+ super(connection, runtime, document);
14
+ }
15
+
16
+ Draw(Connection connection, Ruby runtime, XComponent document, RubyProc proc) {
17
+ super(connection, runtime, document, proc);
18
+ }
19
+
20
+ @Override
21
+ protected void setDefaultOptions(Map<String, Object> options) {
22
+ options.put("FilterName", "draw_pdf_Export");
23
+ }
24
+ }
25
+