diff --git a/teavm-platform/pom.xml b/teavm-platform/pom.xml
index f35121baa..a4fd22179 100644
--- a/teavm-platform/pom.xml
+++ b/teavm-platform/pom.xml
@@ -15,5 +15,10 @@
teavm-core${project.version}
+
+ junit
+ junit
+ test
+
\ No newline at end of file
diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/Resource.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/Resource.java
index f47ac1747..7b50dfe88 100644
--- a/teavm-platform/src/main/java/org/teavm/platform/metadata/Resource.java
+++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/Resource.java
@@ -23,7 +23,7 @@ import java.lang.annotation.Target;
/**
*
Marks a valid resource interface. Resource interface is an interface, that has get* and set* methods,
* according the default convention for JavaBeans. Each property must have both getter and setter.
- * Also each property's must be either primitive value, except for long or valid resource.
+ * Also each property's must be either primitive value (except for long) or a valid resource.
*
* @see MetadataGenerator
* @see ResourceArray
diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java
index 599467059..e798f94cc 100644
--- a/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java
+++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java
@@ -20,6 +20,8 @@ package org.teavm.platform.metadata;
* @author Alexey Andreev
*/
public interface ResourceMap {
+ boolean has(String key);
+
T get(String key);
void put(String key, T value);
diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceArray.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceArray.java
new file mode 100644
index 000000000..c8aca068d
--- /dev/null
+++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceArray.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2014 Alexey Andreev.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.teavm.platform.plugin;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.teavm.platform.metadata.ResourceArray;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+class BuildTimeResourceArray implements ResourceArray {
+ private List data = new ArrayList<>();
+
+ @Override
+ public int size() {
+ return data.size();
+ }
+
+ @Override
+ public T get(int i) {
+ return data.get(i);
+ }
+
+ @Override
+ public void add(T elem) {
+ data.add(elem);
+ }
+}
diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceGetter.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceGetter.java
new file mode 100644
index 000000000..f00aa2e27
--- /dev/null
+++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceGetter.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2014 Alexey Andreev.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.teavm.platform.plugin;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+class BuildTimeResourceGetter implements BuildTimeResourceMethod {
+ private int index;
+
+ public BuildTimeResourceGetter(int index) {
+ this.index = index;
+ }
+
+ @Override
+ public Object invoke(BuildTimeResourceProxy proxy, Object[] args) throws Throwable {
+ return proxy.data[index];
+ }
+}
diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceMap.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceMap.java
new file mode 100644
index 000000000..36174df46
--- /dev/null
+++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceMap.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2014 Alexey Andreev.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.teavm.platform.plugin;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.teavm.platform.metadata.ResourceMap;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+class BuildTimeResourceMap implements ResourceMap {
+ private Map data = new HashMap<>();
+
+ @Override
+ public boolean has(String key) {
+ return data.containsKey(key);
+ }
+
+ @Override
+ public T get(String key) {
+ return data.get(key);
+ }
+
+ @Override
+ public void put(String key, T value) {
+ data.put(key, value);
+ }
+}
diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceMethod.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceMethod.java
new file mode 100644
index 000000000..31f3be541
--- /dev/null
+++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceMethod.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2014 Alexey Andreev.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.teavm.platform.plugin;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+interface BuildTimeResourceMethod {
+ Object invoke(BuildTimeResourceProxy proxy, Object[] args) throws Throwable;
+}
diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxy.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxy.java
new file mode 100644
index 000000000..390acb1e5
--- /dev/null
+++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxy.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2014 Alexey Andreev.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.teavm.platform.plugin;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Map;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+class BuildTimeResourceProxy implements InvocationHandler {
+ private Map methods;
+ Object[] data;
+
+ public BuildTimeResourceProxy(Map methods, Object[] initialData) {
+ this.methods = methods;
+ data = Arrays.copyOf(initialData, initialData.length);
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ return methods.get(method).invoke(this, args);
+ }
+}
diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxyBuilder.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxyBuilder.java
new file mode 100644
index 000000000..b5a09e757
--- /dev/null
+++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxyBuilder.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2014 Alexey Andreev.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.teavm.platform.plugin;
+
+import java.lang.reflect.Method;
+import java.util.*;
+import org.teavm.platform.metadata.Resource;
+import org.teavm.platform.metadata.ResourceArray;
+import org.teavm.platform.metadata.ResourceMap;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+class BuildTimeResourceProxyBuilder {
+ private Map, BuildTimeResourceProxyFactory> factories = new HashMap<>();
+ private static Set> allowedPropertyTypes = new HashSet<>(Arrays.>asList(
+ boolean.class, Boolean.class, byte.class, Byte.class, short.class, Short.class,
+ int.class, Integer.class, float.class, Float.class, double.class, Double.class,
+ String.class, ResourceArray.class, ResourceMap.class));
+
+ public BuildTimeResourceProxy buildProxy(Class> iface) {
+ BuildTimeResourceProxyFactory factory = factories.get(iface);
+ if (factory == null) {
+ factory = createFactory(iface);
+ factories.put(iface, factory);
+ }
+ return factory.create();
+ }
+
+ private BuildTimeResourceProxyFactory createFactory(Class> iface) {
+ return new ProxyFactoryCreation(iface).create();
+ }
+
+ private static class ProxyFactoryCreation {
+ private Class> rootIface;
+ Map> getters = new HashMap<>();
+ Map> setters = new HashMap<>();
+ Map methods = new HashMap<>();
+ private List