pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/jruby/jruby/commit/6886cc0d191dcd883fde1ad87342aba5d5058cfb

" /> Rewire ENV_JAVA to be a read/write mirror of system properties. · jruby/jruby@6886cc0 · GitHub
Skip to content

Commit 6886cc0

Browse files
committed
Rewire ENV_JAVA to be a read/write mirror of system properties.
Normally ENV_JAVA will remain a read-only copy of System properties, but after require 'java', it is replaced with a read-write wrapper. Updates then are propagated into System properties, and updates from outside JRuby are visible.
1 parent 5737ac6 commit 6886cc0

8 files changed

Lines changed: 200 additions & 4 deletions

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
require File.dirname(__FILE__) + "/../spec_helper"
2+
3+
describe "ENV_JAVA" do
4+
before :each do
5+
ENV_JAVA['env.java.spec'] = nil
6+
end
7+
8+
after :each do
9+
ENV_JAVA['env.java.spec'] = nil
10+
end
11+
12+
it "writes to system properties" do
13+
java.lang.System.getProperty('env.java.spec').should == nil
14+
ENV_JAVA['env.java.spec'] = 'foo'
15+
ENV_JAVA['env.java.spec'].should == 'foo'
16+
java.lang.System.getProperty('env.java.spec').should == 'foo'
17+
end
18+
19+
it "reflects changes to system properties" do
20+
ENV_JAVA['env.java.spec'].should == nil
21+
java.lang.System.setProperty('env.java.spec', 'foo')
22+
ENV_JAVA['env.java.spec'].should == 'foo'
23+
java.lang.System.getProperty('env.java.spec').should == 'foo'
24+
end
25+
end

src/org/jruby/RubyDir.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,7 @@ public static IRubyObject getHomeDirectoryPath(ThreadContext context, String use
891891

892892
public static RubyString getHomeDirectoryPath(ThreadContext context) {
893893
Ruby runtime = context.getRuntime();
894-
RubyHash systemHash = (RubyHash) runtime.getObject().getConstant("ENV_JAVA");
894+
IRubyObject systemHash = runtime.getObject().getConstant("ENV_JAVA");
895895
RubyHash envHash = (RubyHash) runtime.getObject().getConstant("ENV");
896896
IRubyObject home = null;
897897

@@ -904,7 +904,7 @@ public static RubyString getHomeDirectoryPath(ThreadContext context) {
904904
}
905905

906906
if (home == null || home.isNil()) {
907-
home = systemHash.op_aref(context, runtime.newString("user.home"));
907+
home = systemHash.callMethod(context, "[]", runtime.newString("user.home"));
908908
}
909909

910910
if (home == null || home.isNil()) {

src/org/jruby/RubyGlobal.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,10 @@ private static void defineGlobalEnvConstants(Ruby runtime) {
283283

284284
// Define System.getProperties() in ENV_JAVA
285285
Map systemProps = environment.getSystemPropertiesMap(runtime);
286-
runtime.defineGlobalConstant("ENV_JAVA", new StringOnlyRubyHash(
287-
runtime, systemProps, runtime.getNil()));
286+
RubyHash systemPropsHash = new ReadOnlySystemPropertiesHash(
287+
runtime, systemProps, runtime.getNil());
288+
systemPropsHash.setFrozen(true);
289+
runtime.defineGlobalConstant("ENV_JAVA", systemPropsHash);
288290
}
289291

290292
/**
@@ -433,6 +435,22 @@ private IRubyObject normalizeEnvString(IRubyObject str) {
433435
}
434436
}
435437

438+
private static class ReadOnlySystemPropertiesHash extends StringOnlyRubyHash {
439+
public ReadOnlySystemPropertiesHash(Ruby runtime, Map valueMap, IRubyObject defaultValue, boolean updateRealENV) {
440+
super(runtime, valueMap, defaultValue, updateRealENV);
441+
}
442+
443+
public ReadOnlySystemPropertiesHash(Ruby runtime, Map valueMap, IRubyObject defaultValue) {
444+
this(runtime, valueMap, defaultValue, false);
445+
}
446+
447+
public void modify() {
448+
if (isFrozen()) {
449+
throw getRuntime().newTypeError("ENV_JAVA is not writable until you require 'java'");
450+
}
451+
}
452+
}
453+
436454
private static class NonEffectiveGlobalVariable extends GlobalVariable {
437455
public NonEffectiveGlobalVariable(Ruby runtime, String name, IRubyObject value) {
438456
super(runtime, name, value);

src/org/jruby/java/proxies/ConcreteJavaProxy.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ public ConcreteJavaProxy(Ruby runtime, RubyClass klazz) {
1717
super(runtime, klazz);
1818
}
1919

20+
public ConcreteJavaProxy(Ruby runtime, RubyClass klazz, Object object) {
21+
super(runtime, klazz, object);
22+
}
23+
2024
public static RubyClass createConcreteJavaProxy(ThreadContext context) {
2125
Ruby runtime = context.getRuntime();
2226

src/org/jruby/java/proxies/JavaProxy.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ public JavaProxy(Ruby runtime, RubyClass klazz) {
5050
super(runtime, klazz);
5151
}
5252

53+
public JavaProxy(Ruby runtime, RubyClass klazz, Object object) {
54+
super(runtime, klazz);
55+
this.object = object;
56+
}
57+
5358
@Override
5459
public Object dataGetStruct() {
5560
// for investigating and eliminating code that causes JavaObject to live

src/org/jruby/java/proxies/MapJavaProxy.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ public MapJavaProxy(Ruby runtime, RubyClass klazz) {
6868
super(runtime, klazz);
6969
}
7070

71+
public MapJavaProxy(Ruby runtime, RubyClass klazz, Map map) {
72+
super(runtime, klazz, map);
73+
}
74+
7175
public static RubyClass createMapJavaProxy(ThreadContext context) {
7276
Ruby runtime = context.getRuntime();
7377

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/***** BEGIN LICENSE BLOCK *****
2+
* Version: CPL 1.0/GPL 2.0/LGPL 2.1
3+
*
4+
* The contents of this file are subject to the Common Public
5+
* License Version 1.0 (the "License"); you may not use this file
6+
* except in compliance with the License. You may obtain a copy of
7+
* the License at http://www.eclipse.org/legal/cpl-v10.html
8+
*
9+
* Software distributed under the License is distributed on an "AS
10+
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11+
* implied. See the License for the specific language governing
12+
* rights and limitations under the License.
13+
*
14+
* Alternatively, the contents of this file may be used under the terms of
15+
* either of the GNU General Public License Version 2 or later (the "GPL"),
16+
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
17+
* in which case the provisions of the GPL or the LGPL are applicable instead
18+
* of those above. If you wish to allow use of your version of this file only
19+
* under the terms of either the GPL or the LGPL, and not to allow others to
20+
* use your version of this file under the terms of the CPL, indicate your
21+
* decision by deleting the provisions above and replace them with the notice
22+
* and other provisions required by the GPL or the LGPL. If you do not delete
23+
* the provisions above, a recipient may use your version of this file under
24+
* the terms of any one of the CPL, the GPL or the LGPL.
25+
***** END LICENSE BLOCK *****/
26+
27+
package org.jruby.java.util;
28+
29+
import org.jruby.runtime.builtin.IRubyObject;
30+
31+
import java.util.Collection;
32+
import java.util.Map;
33+
import java.util.Set;
34+
35+
/**
36+
* A java.lang.Map that defers all methods to System properties.
37+
*/
38+
public class SystemPropertiesMap implements Map {
39+
protected String stringFromObject(Object o) {
40+
if (o instanceof String) {
41+
return (String)o;
42+
} else if (o instanceof IRubyObject) {
43+
return (String)((IRubyObject)o).toJava(String.class);
44+
}
45+
return null;
46+
}
47+
48+
public int size() {
49+
return System.getProperties().size();
50+
}
51+
52+
public boolean isEmpty() {
53+
return false;
54+
}
55+
56+
public boolean containsKey(Object o) {
57+
String key = stringFromObject(o);
58+
if (key != null) {
59+
return System.getProperty(key) != null;
60+
}
61+
return false;
62+
}
63+
64+
public boolean containsValue(Object o) {
65+
String value = stringFromObject(o);
66+
if (value != null) {
67+
return System.getProperties().containsValue(value);
68+
}
69+
return false; //To change body of implemented methods use File | Settings | File Templates.
70+
}
71+
72+
public Object get(Object o) {
73+
String key = stringFromObject(o);
74+
if (key != null) {
75+
return System.getProperty(key);
76+
}
77+
return null; //To change body of implemented methods use File | Settings | File Templates.
78+
}
79+
80+
public Object put(Object s, Object s1) {
81+
String key = stringFromObject(s);
82+
String value = stringFromObject(s1);
83+
if (key != null) {
84+
if (value == null) {
85+
return System.clearProperty(key);
86+
}
87+
return System.setProperty(key, value);
88+
}
89+
return null;
90+
}
91+
92+
public Object remove(Object o) {
93+
String key = stringFromObject(o);
94+
if (key != null) {
95+
return System.clearProperty(key);
96+
}
97+
return null; //To change body of implemented methods use File | Settings | File Templates.
98+
}
99+
100+
public void putAll(Map map) {
101+
for (Map.Entry entry : (Set<Entry>)map.entrySet()) {
102+
String key = stringFromObject(entry.getKey());
103+
String value = stringFromObject(entry.getValue());
104+
if (key != null) {
105+
if (value == null) {
106+
System.clearProperty(key);
107+
} else {
108+
System.setProperty(key, value);
109+
}
110+
}
111+
}
112+
}
113+
114+
public void clear() {
115+
// ignored
116+
}
117+
118+
public Set<Object> keySet() {
119+
return System.getProperties().keySet();
120+
}
121+
122+
public Collection<Object> values() {
123+
return System.getProperties().values();
124+
}
125+
126+
public Set<Entry<Object, Object>> entrySet() {
127+
return System.getProperties().entrySet();
128+
}
129+
}

src/org/jruby/javasupport/Java.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
***** END LICENSE BLOCK *****/
3434
package org.jruby.javasupport;
3535

36+
import org.jruby.java.util.SystemPropertiesMap;
3637
import org.jruby.java.proxies.JavaInterfaceTemplate;
3738
import org.jruby.java.addons.KernelJavaAddons;
3839
import java.io.IOException;
@@ -67,6 +68,7 @@
6768
import org.jruby.RubyString;
6869
import org.jruby.RubyUnboundMethod;
6970
import org.jruby.exceptions.RaiseException;
71+
import org.jruby.java.util.SystemPropertiesMap;
7072
import org.jruby.javasupport.proxy.JavaProxyClass;
7173
import org.jruby.javasupport.proxy.JavaProxyConstructor;
7274
import org.jruby.javasupport.util.RuntimeHelpers;
@@ -114,6 +116,15 @@ public void load(Ruby runtime, boolean wrap) throws IOException {
114116
ajp.includeModule(runtime.getEnumerable());
115117

116118
RubyClassPathVariable.createClassPathVariable(runtime);
119+
120+
// modify ENV_JAVA to be a read/write version
121+
Map systemProps = new SystemPropertiesMap();
122+
runtime.getObject().setConstantQuiet(
123+
"ENV_JAVA",
124+
new MapJavaProxy(
125+
runtime,
126+
(RubyClass)Java.getProxyClass(runtime, JavaClass.get(runtime, SystemPropertiesMap.class)),
127+
systemProps));
117128
}
118129

119130
public static RubyModule createJavaModule(Ruby runtime) {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy