Skip to content

Commit ea9bf42

Browse files
committed
Remove unnecessary lazy initialization, create more singletons
Lazy initialization only makes sense for large objects or objects whose creation is expensive, however this is not the case here. Also removes redundant `{@inheritdoc}` javadoc comments because documentation is inherited by default if no javadoc comment exists.
1 parent 40d4daa commit ea9bf42

File tree

7 files changed

+82
-130
lines changed

7 files changed

+82
-130
lines changed

src/main/java/ca/weblite/objc/Client.java

Lines changed: 11 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,14 @@
1313
* outputs from messages. There are two global instances of this class
1414
* that are used most often:</p>
1515
* <ol>
16-
* <li><strong><code>Client.getInstance()</code></strong> : The default
17-
* client with settings to coerce both inputs and outputs. If you
18-
* need to make a direct call to the Objective-C runtime, this
19-
* is usually the client that you would use.
16+
* <li>{@link #getInstance()}: The default client with settings to coerce
17+
* both inputs and outputs. If you need to make a direct call to the
18+
* Objective-C runtime, this is usually the client that you would use.
2019
* </li>
21-
* <li><strong><code>Client.getRawClient()</code></strong> : Reference
22-
* to a simple client that is set to <em>not</em> coerce input and
23-
* output. This is handy if you want to pass in the raw Pointers
24-
* as parameters, and receive raw pointers as output.
20+
* <li>{@link #getRawClient()}: Reference to a simple client that is set to
21+
* <em>not</em> coerce input and output. This is handy if you want to
22+
* pass in the raw Pointers as parameters, and receive raw pointers as
23+
* output.
2524
* </li>
2625
* </ol>
2726
*
@@ -35,42 +34,28 @@ public class Client {
3534
* Reference to the default client instance with type coercion enabled
3635
* for both inputs and outputs.
3736
*/
38-
private static volatile Client instance;
37+
private static final Client instance = new Client(true, true);
3938

4039
private Client(boolean coerceInputs, boolean coerceOutputs) {
4140
this.coerceInputs = coerceInputs;
4241
this.coerceOutputs = coerceOutputs;
4342
}
4443

45-
private Client() {
46-
this(true, true);
47-
}
48-
4944
/**
5045
* Retrieves the global reference to a client that has both input coercion
5146
* and output coercion enabled.
5247
*
5348
* @return Singleton instance.
5449
*/
5550
public static Client getInstance() {
56-
Client localInstance = instance;
57-
if (localInstance == null) {
58-
// Could also use dedicated lock for `instance` and `rawClient`, but likely not worth it
59-
synchronized (Client.class) {
60-
localInstance = instance;
61-
if (localInstance == null) {
62-
instance = localInstance = new Client();
63-
}
64-
}
65-
}
66-
return localInstance;
51+
return instance;
6752
}
6853

6954
/**
7055
* Reference to a simple client that has type coercion disabled for both
7156
* inputs and outputs.
7257
*/
73-
private static volatile Client rawClient;
58+
private static final Client rawClient = new Client(false, false);
7459

7560
/**
7661
* Retrieves singleton instance to a simple client that has type coercion
@@ -79,19 +64,7 @@ public static Client getInstance() {
7964
* @return a {@link ca.weblite.objc.Client} object.
8065
*/
8166
public static Client getRawClient(){
82-
Client localInstance = rawClient;
83-
84-
if (localInstance == null ){
85-
synchronized(Client.class) {
86-
localInstance = rawClient;
87-
if (localInstance == null) {
88-
localInstance = new Client(false, false);
89-
rawClient = localInstance;
90-
}
91-
}
92-
93-
}
94-
return localInstance;
67+
return rawClient;
9568
}
9669

9770
/**

src/main/java/ca/weblite/objc/TypeMapper.java

Lines changed: 33 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
import ca.weblite.objc.mappers.ScalarMapping;
66
import ca.weblite.objc.mappers.StringMapping;
77
import ca.weblite.objc.mappers.StructureMapping;
8-
import java.util.HashMap;
9-
import java.util.Map;
108

119
/**
1210
*
@@ -22,61 +20,48 @@
2220
* @since 1.1
2321
*/
2422
public class TypeMapper implements TypeMapping {
25-
2623
/**
27-
* Singleton instance to the TypeMapper
24+
* Singleton instance of the TypeMapper
2825
*/
29-
private static TypeMapper instance;
26+
public static final TypeMapper INSTANCE = new TypeMapper();
3027

3128
/**
32-
* Obtains the singleton instance of the TypeMapper
29+
* Obtains the singleton instance of the TypeMapper, i.e. {@link #INSTANCE}.
3330
*
34-
* @return a {@link ca.weblite.objc.TypeMapper} object.
31+
* @return singleton {@code TypeMapper} object.
3532
*/
3633
public static TypeMapper getInstance(){
37-
if ( instance == null ){
38-
instance = new TypeMapper();
39-
}
40-
return instance;
34+
return INSTANCE;
4135
}
4236

37+
private TypeMapper() { }
4338

4439
/**
4540
* Maps signatures to the corresponding TypeMapping object. Signatures
4641
* are <a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html">Objective-C type encodings</a>.
4742
*/
48-
Map<String, TypeMapping> mappers = new HashMap<String,TypeMapping>();
49-
50-
/**
51-
* <p>Constructor for TypeMapper.</p>
52-
*/
53-
public TypeMapper(){
54-
init();
55-
}
56-
57-
58-
private void init(){
59-
addMapping(new ScalarMapping(), "cCiIsSfdlLqQB[:b?#v".split(""));
60-
addMapping(new StringMapping(), "*".split(""));
61-
addMapping(new PointerMapping(), "^");
62-
addMapping(new NSObjectMapping(), "@");
63-
addMapping(new StructureMapping(), "{");
64-
}
65-
66-
/**
67-
* Adds a TypeMapping that is meant to handle one or more signatures.
68-
*
69-
* @param mapping The TypeMapping object meant to handle conversions for
70-
* the given signatures.
71-
* @param signatures One or more signatures following <a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html">Objective-C type encodings</a>.
72-
* @return Self for chaining.
73-
*/
74-
public TypeMapper addMapping(TypeMapping mapping, String... signatures){
75-
76-
for ( int i=0; i<signatures.length; i++){
77-
mappers.put(signatures[i], mapping);
43+
private static TypeMapping getMapping(char typeChar) {
44+
switch (typeChar) {
45+
case 'c': case 'C':
46+
case 'i': case 'I':
47+
case 's': case 'S':
48+
case 'f': case 'd':
49+
case 'l': case 'L':
50+
case 'q': case 'Q':
51+
case 'b': case 'B':
52+
case '[': case ':': case '?': case '#': case 'v':
53+
return ScalarMapping.INSTANCE;
54+
case '*':
55+
return StringMapping.INSTANCE;
56+
case '^':
57+
return PointerMapping.INSTANCE;
58+
case '@':
59+
return NSObjectMapping.INSTANCE;
60+
case '{':
61+
return StructureMapping.INSTANCE;
62+
default:
63+
throw new IllegalArgumentException("Unknown type: " + typeChar);
7864
}
79-
return this;
8065
}
8166

8267
/**
@@ -100,14 +85,9 @@ public Object cToJ(Object cVar, String signature, TypeMapping root) {
10085
signature = signature.substring(offset);
10186
}
10287

103-
String firstChar = signature.substring(0,1);
104-
TypeMapping mapping = mappers.get(firstChar);
105-
if ( mapping == null ){
106-
// We couldn't find a mapper for this type
107-
throw new RuntimeException("No mapper registered for type "+firstChar);
108-
} else {
109-
return mapping.cToJ(cVar, signature, root);
110-
}
88+
char typeChar = signature.charAt(0);
89+
TypeMapping mapping = getMapping(typeChar);
90+
return mapping.cToJ(cVar, signature, root);
11191
}
11292

11393
/**
@@ -138,14 +118,9 @@ public Object jToC(Object jVar, String signature, TypeMapping root) {
138118
signature = signature.substring(offset);
139119
}
140120

141-
String firstChar = signature.substring(0,1);
142-
TypeMapping mapping = mappers.get(firstChar);
143-
if ( mapping == null ){
144-
// We couldn't find a mapper for this type
145-
throw new RuntimeException("No mapper registered for type "+firstChar);
146-
} else {
147-
return mapping.jToC(jVar, signature, root);
148-
}
121+
char typeChar = signature.charAt(0);
122+
TypeMapping mapping = getMapping(typeChar);
123+
return mapping.jToC(jVar, signature, root);
149124
}
150125

151126
}

src/main/java/ca/weblite/objc/mappers/NSObjectMapping.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,22 @@
1616
* @version $Id: $Id
1717
* @since 1.1
1818
*/
19-
public class NSObjectMapping implements TypeMapping{
19+
public class NSObjectMapping implements TypeMapping {
20+
/**
21+
* Singleton instance.
22+
*/
23+
public static final NSObjectMapping INSTANCE = new NSObjectMapping();
24+
25+
private NSObjectMapping() { }
2026

21-
/** {@inheritDoc} */
2227
@Override
2328
public Object cToJ(Object cVar, String signature, TypeMapping root) {
2429
//System.out.println("Mapping NSObject to Java "+cVar+" sig: "+signature);
2530
Pointer cObj = Pointer.NULL;
2631
if ( Pointer.class.isInstance(cVar) ){
2732
cObj = (Pointer)cVar;
2833
} else if (long.class.isInstance(cVar) || Long.class.isInstance(cVar) ){
29-
cObj = new Pointer((Long)cVar);
34+
cObj = new Pointer((long) cVar);
3035
} else {
3136
return cVar;
3237
}
@@ -35,10 +40,7 @@ public Object cToJ(Object cVar, String signature, TypeMapping root) {
3540
return null;
3641
}
3742
String clsName = Runtime.INSTANCE.object_getClassName(cObj);
38-
boolean isString = false;
39-
if ( "NSString".equals(clsName) || "NSTaggedPointerString".equals(clsName) || "NSMutableString".equals(clsName) || "__NSCFString".equals(clsName)){
40-
isString = true;
41-
}
43+
boolean isString = "NSString".equals(clsName) || "NSTaggedPointerString".equals(clsName) || "NSMutableString".equals(clsName) || "__NSCFString".equals(clsName);
4244

4345

4446
////System.out.println("Checking if object is a string "+isString+", "+clsName);
@@ -53,7 +55,6 @@ public Object cToJ(Object cVar, String signature, TypeMapping root) {
5355
}
5456
}
5557

56-
/** {@inheritDoc} */
5758
@Override
5859
public Object jToC(Object jVar, String signature, TypeMapping root) {
5960
if ( jVar == null ){

src/main/java/ca/weblite/objc/mappers/PointerMapping.java

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
package ca.weblite.objc.mappers;
22

3-
import java.util.HashMap;
4-
import java.util.Map;
5-
63
import com.sun.jna.Pointer;
74

85
import ca.weblite.objc.TypeMapping;
@@ -15,26 +12,19 @@
1512
* @since 1.1
1613
*/
1714
public class PointerMapping implements TypeMapping {
18-
19-
Map<String,TypeMapping> mappers = new HashMap<String, TypeMapping>();
20-
2115
/**
22-
* <p>Constructor for PointerMapping.</p>
16+
* Singleton instance.
2317
*/
24-
public PointerMapping(){
25-
26-
27-
28-
}
18+
public static final PointerMapping INSTANCE = new PointerMapping();
19+
20+
private PointerMapping() { }
2921

30-
/** {@inheritDoc} */
3122
@Override
3223
public Object cToJ(Object cVar, String signature, TypeMapping root) {
3324
if ( Pointer.class.isInstance(cVar)) return cVar;
34-
return new Pointer((Long)cVar);
25+
return new Pointer((long) cVar);
3526
}
3627

37-
/** {@inheritDoc} */
3828
@Override
3929
public Object jToC(Object jVar, String signature, TypeMapping root) {
4030
// After some difficult deliberation I've decided that it is

src/main/java/ca/weblite/objc/mappers/ScalarMapping.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,13 @@
1010
* @since 1.1
1111
*/
1212
public class ScalarMapping implements TypeMapping {
13-
14-
/** {@inheritDoc} */
13+
/**
14+
* Singleton instance.
15+
*/
16+
public static final ScalarMapping INSTANCE = new ScalarMapping();
17+
18+
private ScalarMapping() { }
19+
1520
@Override
1621
public Object cToJ(Object cVar, String signature, TypeMapping root) {
1722
//System.out.println("C to J for signature "+signature);
@@ -27,14 +32,13 @@ public Object cToJ(Object cVar, String signature, TypeMapping root) {
2732
case 'c':
2833
return (byte) cObj;
2934
case 'B':
30-
return cObj > 0L ? true:false;
35+
return cObj > 0L;
3136
}
3237
}
3338

3439
return cVar;
3540
}
3641

37-
/** {@inheritDoc} */
3842
@Override
3943
public Object jToC(Object jVar, String signature, TypeMapping root) {
4044
return jVar;

src/main/java/ca/weblite/objc/mappers/StringMapping.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
package ca.weblite.objc.mappers;
22

3-
import ca.weblite.objc.TypeMapping;
43
import com.sun.jna.Pointer;
54

5+
import ca.weblite.objc.TypeMapping;
6+
67
/**
78
* <p>StringMapping class.</p>
89
*
910
* @author shannah
1011
* @version $Id: $Id
1112
* @since 1.1
1213
*/
13-
public class StringMapping implements TypeMapping{
14-
15-
/** {@inheritDoc} */
14+
public class StringMapping implements TypeMapping {
15+
/**
16+
* Singleton instance.
17+
*/
18+
public static final StringMapping INSTANCE = new StringMapping();
19+
20+
private StringMapping() { }
21+
1622
@Override
1723
public Object cToJ(Object cVar, String signature, TypeMapping root) {
1824
return new Pointer((Long)cVar).getString(0);
1925
}
2026

21-
/** {@inheritDoc} */
2227
@Override
2328
public Object jToC(Object jVar, String signature, TypeMapping root) {
2429
return jVar;

src/main/java/ca/weblite/objc/mappers/StructureMapping.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,18 @@
1010
* @since 1.1
1111
*/
1212
public class StructureMapping implements TypeMapping {
13+
/**
14+
* Singleton instance.
15+
*/
16+
public static final StructureMapping INSTANCE = new StructureMapping();
1317

14-
/** {@inheritDoc} */
18+
private StructureMapping() { }
19+
1520
@Override
1621
public Object cToJ(Object cVar, String signature, TypeMapping root) {
1722
return cVar;
1823
}
1924

20-
/** {@inheritDoc} */
2125
@Override
2226
public Object jToC(Object jVar, String signature, TypeMapping root) {
2327
return jVar;

0 commit comments

Comments
 (0)