librepdf 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+