aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrazyboblee <crazyboblee@d779f126-a31b-0410-b53b-1d3aecad763e>2009-02-05 06:23:52 +0000
committercrazyboblee <crazyboblee@d779f126-a31b-0410-b53b-1d3aecad763e>2009-02-05 06:23:52 +0000
commitc112063529baac332325fde0f2616e04dd073aee (patch)
tree952570627cb099f30d41f6838fa31be8c231a45f
parent210bf43ac2ce742fabe0ab881c0ebfa50a4e32b2 (diff)
downloadguice-c112063529baac332325fde0f2616e04dd073aee.tar.gz
Added XML example.
git-svn-id: https://google-guice.googlecode.com/svn/trunk@831 d779f126-a31b-0410-b53b-1d3aecad763e
-rw-r--r--examples/examples.iml23
-rw-r--r--examples/src/example/xml/Contact.java5
-rw-r--r--examples/src/example/xml/Contacts.java5
-rw-r--r--examples/src/example/xml/FlashMemory.java10
-rw-r--r--examples/src/example/xml/FromFlash.java7
-rw-r--r--examples/src/example/xml/FromSim.java7
-rw-r--r--examples/src/example/xml/Main.java48
-rw-r--r--examples/src/example/xml/Phone.java14
-rw-r--r--examples/src/example/xml/SimCard.java10
-rw-r--r--examples/src/example/xml/XmlBeanModule.java227
-rw-r--r--examples/src/example/xml/phone.xml5
-rw-r--r--lib/build/safesax.jarbin0 -> 10055 bytes
12 files changed, 361 insertions, 0 deletions
diff --git a/examples/examples.iml b/examples/examples.iml
new file mode 100644
index 00000000..9f903749
--- /dev/null
+++ b/examples/examples.iml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="guice" />
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/../lib/build/safesax.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntryProperties />
+ </component>
+</module>
+
diff --git a/examples/src/example/xml/Contact.java b/examples/src/example/xml/Contact.java
new file mode 100644
index 00000000..160dbdcb
--- /dev/null
+++ b/examples/src/example/xml/Contact.java
@@ -0,0 +1,5 @@
+package example.xml;
+
+public class Contact {
+
+}
diff --git a/examples/src/example/xml/Contacts.java b/examples/src/example/xml/Contacts.java
new file mode 100644
index 00000000..1efea32d
--- /dev/null
+++ b/examples/src/example/xml/Contacts.java
@@ -0,0 +1,5 @@
+package example.xml;
+
+public interface Contacts {
+ Iterable<Contact> findByName(String name);
+}
diff --git a/examples/src/example/xml/FlashMemory.java b/examples/src/example/xml/FlashMemory.java
new file mode 100644
index 00000000..14294f44
--- /dev/null
+++ b/examples/src/example/xml/FlashMemory.java
@@ -0,0 +1,10 @@
+package example.xml;
+
+import java.util.Collections;
+
+public class FlashMemory implements Contacts {
+
+ public Iterable<Contact> findByName(String name) {
+ return Collections.emptyList();
+ }
+}
diff --git a/examples/src/example/xml/FromFlash.java b/examples/src/example/xml/FromFlash.java
new file mode 100644
index 00000000..def20447
--- /dev/null
+++ b/examples/src/example/xml/FromFlash.java
@@ -0,0 +1,7 @@
+package example.xml;
+
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.*;
+
+@Retention(RUNTIME)
+public @interface FromFlash {} \ No newline at end of file
diff --git a/examples/src/example/xml/FromSim.java b/examples/src/example/xml/FromSim.java
new file mode 100644
index 00000000..47ed4164
--- /dev/null
+++ b/examples/src/example/xml/FromSim.java
@@ -0,0 +1,7 @@
+package example.xml;
+
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.*;
+
+@Retention(RUNTIME)
+public @interface FromSim {}
diff --git a/examples/src/example/xml/Main.java b/examples/src/example/xml/Main.java
new file mode 100644
index 00000000..6983dec8
--- /dev/null
+++ b/examples/src/example/xml/Main.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (C) 2007 Google Inc.
+ *
+ * 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 example.xml;
+
+import com.google.inject.Guice;
+import com.google.inject.AbstractModule;
+import com.google.inject.Injector;
+import java.net.URL;
+
+/**
+ *
+ *
+ */
+public class Main {
+
+ public static void main(String[] args) {
+ final URL xmlUrl = Main.class.getResource("phone.xml");
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ protected void configure() {
+ bind(Contacts.class).to(SimCard.class);
+ install(new XmlBeanModule(xmlUrl));
+ }
+ });
+
+ Phone phone = injector.getInstance(Phone.class);
+
+ if (phone.getContacts() == null) {
+ throw new AssertionError();
+ } else {
+ System.out.println("It worked!");
+ }
+ }
+}
diff --git a/examples/src/example/xml/Phone.java b/examples/src/example/xml/Phone.java
new file mode 100644
index 00000000..a48ddcec
--- /dev/null
+++ b/examples/src/example/xml/Phone.java
@@ -0,0 +1,14 @@
+package example.xml;
+
+public class Phone {
+
+ Contacts contacts;
+
+ public void setContacts(Contacts contacts) {
+ this.contacts = contacts;
+ }
+
+ public Contacts getContacts() {
+ return contacts;
+ }
+}
diff --git a/examples/src/example/xml/SimCard.java b/examples/src/example/xml/SimCard.java
new file mode 100644
index 00000000..71cf39bd
--- /dev/null
+++ b/examples/src/example/xml/SimCard.java
@@ -0,0 +1,10 @@
+package example.xml;
+
+import java.util.Collections;
+
+public class SimCard implements Contacts {
+
+ public Iterable<Contact> findByName(String name) {
+ return Collections.emptyList();
+ }
+} \ No newline at end of file
diff --git a/examples/src/example/xml/XmlBeanModule.java b/examples/src/example/xml/XmlBeanModule.java
new file mode 100644
index 00000000..8701d68a
--- /dev/null
+++ b/examples/src/example/xml/XmlBeanModule.java
@@ -0,0 +1,227 @@
+package example.xml;
+
+import com.google.inject.Key;
+import com.google.inject.Module;
+import com.google.inject.Provider;
+import com.google.inject.Binder;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import safesax.Element;
+import safesax.ElementListener;
+import safesax.Parsers;
+import safesax.RootElement;
+import safesax.StartElementListener;
+
+public class XmlBeanModule implements Module {
+
+ final URL xmlUrl;
+
+ Locator locator;
+ Binder originalBinder;
+ BeanBuilder beanBuilder;
+
+ public XmlBeanModule(URL xmlUrl) {
+ this.xmlUrl = xmlUrl;
+ }
+
+ public void configure(Binder binder) {
+ this.originalBinder = binder;
+
+ try {
+ RootElement beans = new RootElement("beans");
+ locator = beans.getLocator();
+
+ Element bean = beans.getChild("bean");
+ bean.setElementListener(new BeanListener());
+
+ Element property = bean.getChild("property");
+ property.setStartElementListener(new PropertyListener());
+
+ Reader in = new InputStreamReader(xmlUrl.openStream());
+ Parsers.parse(in, beans.getContentHandler());
+ }
+ catch (Exception e) {
+ originalBinder.addError(e);
+ }
+ }
+
+ /** Handles "binding" elements. */
+ class BeanListener implements ElementListener {
+
+ public void start(final Attributes attributes) {
+ Binder sourced = originalBinder.withSource(xmlSource());
+
+ String typeString = attributes.getValue("type");
+
+ // Make sure 'type' is present.
+ if (typeString == null) {
+ sourced.addError("Missing 'type' attribute.");
+ return;
+ }
+
+ // Resolve 'type'.
+ Class<?> type;
+ try {
+ type = Class.forName(typeString);
+ }
+ catch (ClassNotFoundException e) {
+ sourced.addError(e);
+ return;
+ }
+
+ // Look for a no-arg constructor.
+ try {
+ type.getConstructor();
+ }
+ catch (NoSuchMethodException e) {
+ sourced.addError("%s doesn't have a no-arg constructor.");
+ return;
+ }
+
+ // Create a bean builder for the given type.
+ beanBuilder = new BeanBuilder(type);
+ }
+
+ public void end() {
+ if (beanBuilder != null) {
+ beanBuilder.build();
+ beanBuilder = null;
+ }
+ }
+ }
+
+ /** Handles "property" elements. */
+ class PropertyListener implements StartElementListener {
+
+ public void start(final Attributes attributes) {
+ Binder sourced = originalBinder.withSource(xmlSource());
+
+ if (beanBuilder == null) {
+ // We must have already run into an error.
+ return;
+ }
+
+ // Check for 'name'.
+ String name = attributes.getValue("name");
+ if (name == null) {
+ sourced.addError("Missing attribute name.");
+ return;
+ }
+
+ Class<?> type = beanBuilder.type;
+
+ // Find setter method for the given property name.
+ String setterName = "set" + capitalize(name);
+ Method setter = null;
+ for (Method method : type.getMethods()) {
+ if (method.getName().equals(setterName)) {
+ setter = method;
+ break;
+ }
+ }
+ if (setter == null) {
+ sourced.addError("%s.%s() not found.", type.getName(), setterName);
+ return;
+ }
+
+ // Validate number of parameters.
+ Type[] parameterTypes = setter.getGenericParameterTypes();
+ if (parameterTypes.length != 1) {
+ sourced.addError("%s.%s() must take one argument.",
+ setterName, type.getName());
+ return;
+ }
+
+ // Add property descriptor to builder.
+ Provider<?> provider = sourced.getProvider(Key.get(parameterTypes[0]));
+ beanBuilder.properties.add(
+ new Property(setter, provider));
+ }
+ }
+
+ static String capitalize(String s) {
+ return Character.toUpperCase(s.charAt(0)) +
+ s.substring(1);
+ }
+
+ static class Property {
+
+ final Method setter;
+ final Provider<?> provider;
+
+ Property(Method setter, Provider<?> provider) {
+ this.setter = setter;
+ this.provider = provider;
+ }
+
+ void setOn(Object o) {
+ try {
+ setter.invoke(o, provider.get());
+ }
+ catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ catch (InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ class BeanBuilder {
+
+ final List<Property> properties = new ArrayList<Property>();
+ final Class<?> type;
+
+ BeanBuilder(Class<?> type) {
+ this.type = type;
+ }
+
+ void build() {
+ addBinding(type);
+ }
+
+ <T> void addBinding(Class<T> type) {
+ originalBinder.withSource(xmlSource())
+ .bind(type).toProvider(new BeanProvider<T>(type, properties));
+ }
+ }
+
+ static class BeanProvider<T> implements Provider<T> {
+
+ final Class<T> type;
+ final List<Property> properties;
+
+ BeanProvider(Class<T> type, List<Property> properties) {
+ this.type = type;
+ this.properties = properties;
+ }
+
+ public T get() {
+ try {
+ T t = type.newInstance();
+ for (Property property : properties) {
+ property.setOn(t);
+ }
+ return t;
+ }
+ catch (InstantiationException e) {
+ throw new RuntimeException(e);
+ }
+ catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ Object xmlSource() {
+ return xmlUrl + ":" + locator.getLineNumber();
+ }
+}
diff --git a/examples/src/example/xml/phone.xml b/examples/src/example/xml/phone.xml
new file mode 100644
index 00000000..b14605e0
--- /dev/null
+++ b/examples/src/example/xml/phone.xml
@@ -0,0 +1,5 @@
+<beans>
+ <bean type="example.xml.Phone">
+ <property name="contacts"/>
+ </bean>
+</beans> \ No newline at end of file
diff --git a/lib/build/safesax.jar b/lib/build/safesax.jar
new file mode 100644
index 00000000..e54b10c2
--- /dev/null
+++ b/lib/build/safesax.jar
Binary files differ