aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/context/common/JavaTransitiveInstancesKey.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/context/common/JavaTransitiveInstancesKey.java')
-rw-r--r--subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/context/common/JavaTransitiveInstancesKey.java165
1 files changed, 165 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/context/common/JavaTransitiveInstancesKey.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/context/common/JavaTransitiveInstancesKey.java
new file mode 100644
index 00000000..eb972c2d
--- /dev/null
+++ b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/context/common/JavaTransitiveInstancesKey.java
@@ -0,0 +1,165 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Bergmann Gabor, Istvan Rath and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package tools.refinery.viatra.runtime.matchers.context.common;
10
11
12
13/**
14 * Instance tuples are of form (x), where object x is an instance of the given Java class or its subclasses.
15 * <p> Fine print 1: classes with the same name are considered equivalent.
16 * Can be instantiated with class name, even if the class itself is not loaded yet; but if the class is available, passing it in the constructor is beneficial to avoid classloading troubles.
17 * <p> Fine print 2: primitive types (char, etc.) are transparently treated as their wrapper class (Character, etc.).
18 * <p> Non-enumerable type, can only be checked.
19 * <p> Stateless type (objects can't change their type)
20 * @author Bergmann Gabor
21 *
22*/
23public class JavaTransitiveInstancesKey extends BaseInputKeyWrapper<String> {
24
25 /**
26 * The actual Class whose (transitive) instances this relation contains. Can be null at compile time, if only the name is available.
27 * Can be a primitive.
28 */
29 private Class<?> cachedOriginalInstanceClass;
30
31 /**
32 * Same as {@link #cachedOriginalInstanceClass}, but primitive classes are replaced with their wrapper classes (e.g. int --> java.lang.Integer).
33 */
34 private Class<?> cachedWrapperInstanceClass;
35
36 /**
37 * Preferred constructor.
38 */
39 public JavaTransitiveInstancesKey(Class<?> instanceClass) {
40 this(primitiveTypeToWrapperClass(instanceClass).getName());
41 this.cachedOriginalInstanceClass = instanceClass;
42 }
43
44 /**
45 * Call this constructor only in contexts where the class itself is not available for loading, e.g. it has not yet been compiled.
46 */
47 public JavaTransitiveInstancesKey(String className) {
48 super(className);
49 }
50
51
52 /**
53 * Returns null if class cannot be loaded.
54 */
55 private Class<?> getOriginalInstanceClass() {
56 if (cachedOriginalInstanceClass == null) {
57 try {
58 resolveClassInternal();
59 } catch (ClassNotFoundException e) {
60 // class not yet available at this point
61 }
62 }
63 return cachedOriginalInstanceClass;
64 }
65
66
67 /**
68 * @return non-null instance class
69 * @throws ClassNotFoundException
70 */
71 private Class<?> forceGetOriginalInstanceClass() throws ClassNotFoundException {
72 if (cachedOriginalInstanceClass == null) {
73 resolveClassInternal();
74 }
75 return cachedOriginalInstanceClass;
76 }
77
78 /**
79 * @return non-null instance class, wrapped if primitive class
80 * @throws ClassNotFoundException
81 */
82 public Class<?> forceGetWrapperInstanceClass() throws ClassNotFoundException {
83 forceGetOriginalInstanceClass();
84 return getWrapperInstanceClass();
85 }
86 /**
87 * @return non-null instance class, wrapped if primitive class
88 * @throws ClassNotFoundException
89 */
90 public Class<?> forceGetInstanceClass() throws ClassNotFoundException {
91 return forceGetWrapperInstanceClass();
92 }
93
94 /**
95 * @return instance class, wrapped if primitive class, null if class cannot be loaded
96 */
97 public Class<?> getWrapperInstanceClass() {
98 if (cachedWrapperInstanceClass == null) {
99 cachedWrapperInstanceClass = primitiveTypeToWrapperClass(getOriginalInstanceClass());
100 }
101 return cachedWrapperInstanceClass;
102 }
103 /**
104 * @return instance class, wrapped if primitive class, null if class cannot be loaded
105 */
106 public Class<?> getInstanceClass() {
107 return getWrapperInstanceClass();
108 }
109
110 private void resolveClassInternal() throws ClassNotFoundException {
111 cachedOriginalInstanceClass = Class.forName(wrappedKey);
112 }
113
114 @Override
115 public String getPrettyPrintableName() {
116 getWrapperInstanceClass();
117 return cachedWrapperInstanceClass == null ? wrappedKey == null ? "<null>" : wrappedKey : cachedWrapperInstanceClass.getName();
118 }
119
120 @Override
121 public String getStringID() {
122 return "javaClass#"+ getPrettyPrintableName();
123 }
124
125 @Override
126 public int getArity() {
127 return 1;
128 }
129
130 @Override
131 public boolean isEnumerable() {
132 return false;
133 }
134
135 @Override
136 public String toString() {
137 return this.getPrettyPrintableName();
138 }
139
140 private static Class<?> primitiveTypeToWrapperClass(Class<?> instanceClass) {
141 if (instanceClass != null && instanceClass.isPrimitive()) {
142 if (Void.TYPE.equals(instanceClass))
143 return Void.class;
144 if (Boolean.TYPE.equals(instanceClass))
145 return Boolean.class;
146 if (Character.TYPE.equals(instanceClass))
147 return Character.class;
148 if (Byte.TYPE.equals(instanceClass))
149 return Byte.class;
150 if (Short.TYPE.equals(instanceClass))
151 return Short.class;
152 if (Integer.TYPE.equals(instanceClass))
153 return Integer.class;
154 if (Long.TYPE.equals(instanceClass))
155 return Long.class;
156 if (Float.TYPE.equals(instanceClass))
157 return Float.class;
158 if (Double.TYPE.equals(instanceClass))
159 return Double.class;
160 }
161 return instanceClass;
162 }
163
164
165}