From 3cc93b57987e7f7590fe6ed65bc380b50e514c92 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Wed, 29 Aug 2012 11:18:06 -0500 Subject: [PATCH] adding jetty-spring module --- jetty-spring/README.TXT | 5 + jetty-spring/pom.xml | 65 ++++++++ .../src/main/config/etc/jetty-spring.xml | 76 ++++++++++ .../java/org/eclipse/jetty/spring/Main.java | 38 +++++ .../java/org/eclipse/jetty/spring/Server.java | 39 +++++ .../spring/SpringConfigurationProcessor.java | 141 ++++++++++++++++++ .../SpringConfigurationProcessorFactory.java | 43 ++++++ ...se.jetty.xml.ConfigurationProcessorFactory | 1 + .../spring/SpringXmlConfigurationTest.java | 141 ++++++++++++++++++ .../jetty/spring/TestConfiguration.java | 137 +++++++++++++++++ .../org/mortbay/jetty/spring/configure.xml | 33 ++++ .../org/mortbay/jetty/spring/jetty-deploy.xml | 36 +++++ .../org/mortbay/jetty/spring/jetty.xml | 44 ++++++ 13 files changed, 799 insertions(+) create mode 100644 jetty-spring/README.TXT create mode 100644 jetty-spring/pom.xml create mode 100644 jetty-spring/src/main/config/etc/jetty-spring.xml create mode 100644 jetty-spring/src/main/java/org/eclipse/jetty/spring/Main.java create mode 100644 jetty-spring/src/main/java/org/eclipse/jetty/spring/Server.java create mode 100644 jetty-spring/src/main/java/org/eclipse/jetty/spring/SpringConfigurationProcessor.java create mode 100644 jetty-spring/src/main/java/org/eclipse/jetty/spring/SpringConfigurationProcessorFactory.java create mode 100644 jetty-spring/src/main/resources/META-INF/services/org.eclipse.jetty.xml.ConfigurationProcessorFactory create mode 100644 jetty-spring/src/test/java/org/eclipse/jetty/spring/SpringXmlConfigurationTest.java create mode 100644 jetty-spring/src/test/java/org/eclipse/jetty/spring/TestConfiguration.java create mode 100644 jetty-spring/src/test/resources/org/mortbay/jetty/spring/configure.xml create mode 100644 jetty-spring/src/test/resources/org/mortbay/jetty/spring/jetty-deploy.xml create mode 100644 jetty-spring/src/test/resources/org/mortbay/jetty/spring/jetty.xml diff --git a/jetty-spring/README.TXT b/jetty-spring/README.TXT new file mode 100644 index 00000000000..40f631c8f30 --- /dev/null +++ b/jetty-spring/README.TXT @@ -0,0 +1,5 @@ +This jetty module is an example of how spring can be used to +configure and run Jetty. + + + diff --git a/jetty-spring/pom.xml b/jetty-spring/pom.xml new file mode 100644 index 00000000000..30046fd1a66 --- /dev/null +++ b/jetty-spring/pom.xml @@ -0,0 +1,65 @@ + + + org.eclipse.jetty + jetty-project + 9.0.0-SNAPSHOT + + 4.0.0 + jetty-spring + Example :: Jetty Spring + + + 2.5.6 + target/dependencies + + + + install + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + + config + + + + + + + + + + org.eclipse.jetty + jetty-webapp + ${project.version} + + + org.eclipse.jetty + jetty-plus + ${project.version} + + + org.eclipse.jetty + jetty-deploy + ${project.version} + + + org.springframework + spring + ${spring-version} + + + junit + junit + test + + + diff --git a/jetty-spring/src/main/config/etc/jetty-spring.xml b/jetty-spring/src/main/config/etc/jetty-spring.xml new file mode 100644 index 00000000000..282a3a76e9e --- /dev/null +++ b/jetty-spring/src/main/config/etc/jetty-spring.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jetty-spring/src/main/java/org/eclipse/jetty/spring/Main.java b/jetty-spring/src/main/java/org/eclipse/jetty/spring/Main.java new file mode 100644 index 00000000000..f2dd4611b2b --- /dev/null +++ b/jetty-spring/src/main/java/org/eclipse/jetty/spring/Main.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.spring; + +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.xml.XmlConfiguration; + + +/* ------------------------------------------------------------ */ +/** Run Jetty from Spring configuration. + * @see jetty-spring.xml + */ +public class Main +{ + public static void main(String[] args) throws Exception + { + Resource config = Resource.newResource(args.length == 1?args[0]:"src/main/config/etc/jetty-spring.xml"); + XmlConfiguration.main(new String[]{config.getFile().getAbsolutePath()}); + + } +} diff --git a/jetty-spring/src/main/java/org/eclipse/jetty/spring/Server.java b/jetty-spring/src/main/java/org/eclipse/jetty/spring/Server.java new file mode 100644 index 00000000000..d9a86ca2fb1 --- /dev/null +++ b/jetty-spring/src/main/java/org/eclipse/jetty/spring/Server.java @@ -0,0 +1,39 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.spring; + +import java.util.Collection; + + +/* ------------------------------------------------------------ */ +/** + * Convenience class for jetty with Spring. + * This class provides a setBeans method as an alternate + * access to the {@link #addBean(Object)} API. + */ +public class Server extends org.eclipse.jetty.server.Server +{ + public void setBeans(Collection beans) + { + for (Object o:beans) + addBean(o); + } + +} diff --git a/jetty-spring/src/main/java/org/eclipse/jetty/spring/SpringConfigurationProcessor.java b/jetty-spring/src/main/java/org/eclipse/jetty/spring/SpringConfigurationProcessor.java new file mode 100644 index 00000000000..4158c0b680d --- /dev/null +++ b/jetty-spring/src/main/java/org/eclipse/jetty/spring/SpringConfigurationProcessor.java @@ -0,0 +1,141 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.spring; + +import java.net.URL; +import java.util.Arrays; +import java.util.Map; + +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.xml.ConfigurationProcessor; +import org.eclipse.jetty.xml.ConfigurationProcessorFactory; +import org.eclipse.jetty.xml.XmlConfiguration; +import org.eclipse.jetty.xml.XmlParser; +import org.springframework.beans.factory.xml.XmlBeanFactory; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; + +/** + * Spring ConfigurationProcessor + *

+ * A {@link ConfigurationProcessor} that uses a spring XML file to emulate the {@link XmlConfiguration} format. + *

+ * {@link XmlConfiguration} expects a primary object that is either passed in to a call to {@link #configure(Object)} + * or that is constructed by a call to {@link #configure()}. This processor looks for a bean definition + * with an id, name or alias of "Main" as uses that as the primary bean. + *

+ * The objects mapped by {@link XmlConfiguration#getIdMap()} are set as singletons before any configuration calls + * and if the spring configuration file contains a definition for the singleton id, the the singleton is updated + * with a call to {@link XmlBeanFactory#configureBean(Object, String)}. + *

+ * The property map obtained via {@link XmlConfiguration#getProperties()} is set as a singleton called "properties" + * and values can be accessed by somewhat verbose + * usage of {@link org.springframework.beans.factory.config.MethodInvokingFactoryBean}. + *

+ * This processor is returned by the {@link SpringConfigurationProcessorFactory} for any XML document whos first + * element is "beans". The factory is discovered by a {@link ServiceLoader} for {@link ConfigurationProcessorFactory}. + */ +public class SpringConfigurationProcessor implements ConfigurationProcessor +{ + static final Logger __log = org.eclipse.jetty.util.log.Log.getLogger(SpringConfigurationProcessor.class.getName()); + + Map _idMap; + Map _propertyMap; + XmlBeanFactory _beanFactory; + String _main; + + public void init(URL url, XmlParser.Node config, Map idMap, Map properties) + { + try + { + _idMap=idMap; + _propertyMap=properties; + + Resource resource = (url!=null) + ?new UrlResource(url) + :new ByteArrayResource((""+config).getBytes("UTF-8")); + + _beanFactory=new XmlBeanFactory(resource); + + } + catch(Exception e) + { + throw new RuntimeException(e); + } + } + + public Object configure(Object obj) throws Exception + { + doConfigure(); + return _beanFactory.configureBean(obj,_main); + } + + /** + * Return a configured bean. If a bean has the id or alias of "Main", then it is returned, otherwise the first bean in the file is returned. + * @see org.eclipse.jetty.xml.ConfigurationProcessor#configure() + */ + public Object configure() throws Exception + { + doConfigure(); + return _beanFactory.getBean(_main); + } + + private void doConfigure() + { + _beanFactory.registerSingleton("properties",_propertyMap); + + // Look for the main bean; + for (String bean : _beanFactory.getBeanDefinitionNames()) + { + __log.debug("{} - {}",bean,Arrays.asList(_beanFactory.getAliases(bean))); + String[] aliases = _beanFactory.getAliases(bean); + if ("Main".equals(bean) || aliases!=null && Arrays.asList(aliases).contains("Main")) + { + _main=bean; + break; + } + } + if (_main==null) + _main=_beanFactory.getBeanDefinitionNames()[0]; + + // Register id beans as singletons + __log.debug("idMap {}",_idMap); + for (String id : _idMap.keySet()) + { + __log.debug("register {}",id); + _beanFactory.registerSingleton(id,_idMap.get(id)); + } + + // Apply configuration to existing singletons + for (String id : _idMap.keySet()) + { + if (_beanFactory.containsBeanDefinition(id)) + { + __log.debug("reconfigure {}",id); + _beanFactory.configureBean(_idMap.get(id),id); + } + } + + // Extract id's for next time. + for (String id : _beanFactory.getSingletonNames()) + _idMap.put(id,_beanFactory.getBean(id)); + } +} diff --git a/jetty-spring/src/main/java/org/eclipse/jetty/spring/SpringConfigurationProcessorFactory.java b/jetty-spring/src/main/java/org/eclipse/jetty/spring/SpringConfigurationProcessorFactory.java new file mode 100644 index 00000000000..44a35e957e4 --- /dev/null +++ b/jetty-spring/src/main/java/org/eclipse/jetty/spring/SpringConfigurationProcessorFactory.java @@ -0,0 +1,43 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.spring; + +import org.eclipse.jetty.xml.ConfigurationProcessor; +import org.eclipse.jetty.xml.ConfigurationProcessorFactory; +import org.eclipse.jetty.xml.XmlConfiguration; + +/** + * Spring ConfigurationProcessor Factory + *

+ * Create a {@link SpringConfigurationProcessor} for XML documents with a "beans" element. + * The factory is discovered by a {@link ServiceLoader} for {@link ConfigurationProcessorFactory}. + * @see SpringConfigurationProcessor + * @see XmlConfiguration + * + */ +public class SpringConfigurationProcessorFactory implements ConfigurationProcessorFactory +{ + public ConfigurationProcessor getConfigurationProcessor(String dtd, String tag) + { + if ("beans".equals(tag)) + return new SpringConfigurationProcessor(); + return null; + } +} diff --git a/jetty-spring/src/main/resources/META-INF/services/org.eclipse.jetty.xml.ConfigurationProcessorFactory b/jetty-spring/src/main/resources/META-INF/services/org.eclipse.jetty.xml.ConfigurationProcessorFactory new file mode 100644 index 00000000000..0289454079c --- /dev/null +++ b/jetty-spring/src/main/resources/META-INF/services/org.eclipse.jetty.xml.ConfigurationProcessorFactory @@ -0,0 +1 @@ +org.eclipse.jetty.spring.SpringConfigurationProcessorFactory diff --git a/jetty-spring/src/test/java/org/eclipse/jetty/spring/SpringXmlConfigurationTest.java b/jetty-spring/src/test/java/org/eclipse/jetty/spring/SpringXmlConfigurationTest.java new file mode 100644 index 00000000000..50db77baa78 --- /dev/null +++ b/jetty-spring/src/test/java/org/eclipse/jetty/spring/SpringXmlConfigurationTest.java @@ -0,0 +1,141 @@ +// ======================================================================== +// Copyright (c) 2006-2009 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== + +package org.eclipse.jetty.spring; + +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.jetty.spring.Server; +import org.eclipse.jetty.xml.XmlConfiguration; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; + +import static junit.framework.Assert.assertEquals; + +public class SpringXmlConfigurationTest +{ + protected String _configure="org/mortbay/jetty/spring/configure.xml"; + + @Before + public void init() throws Exception + { + // Jetty's XML configuration will make use of java.util.ServiceLoader + // to load the proper ConfigurationProcessorFactory, so these tests + // will always fail in JDK 5. + + String javaVersion = System.getProperty("java.version"); + Pattern regexp = Pattern.compile("1\\.(\\d{1})\\..*"); + Matcher matcher = regexp.matcher(javaVersion); + if (matcher.matches()) + { + String minor = matcher.group(1); + Assume.assumeTrue(Integer.parseInt(minor) > 5); + } + } + + @Test + public void testPassedObject() throws Exception + { + TestConfiguration.VALUE=77; + + URL url = SpringXmlConfigurationTest.class.getClassLoader().getResource(_configure); + XmlConfiguration configuration = new XmlConfiguration(url); + + Map properties = new HashMap(); + properties.put("test", "xxx"); + + TestConfiguration nested = new TestConfiguration(); + nested.setTestString0("nested"); + configuration.getIdMap().put("nested",nested); + + TestConfiguration tc = new TestConfiguration(); + tc.setTestString0("preconfig"); + tc.setTestInt0(42); + configuration.getProperties().putAll(properties); + + tc=(TestConfiguration)configuration.configure(tc); + + assertEquals("preconfig",tc.getTestString0()); + assertEquals(42,tc.getTestInt0()); + assertEquals("SetValue",tc.getTestString1()); + assertEquals(1,tc.getTestInt1()); + + assertEquals("nested",tc.getNested().getTestString0()); + assertEquals("nested",tc.getNested().getTestString1()); + assertEquals("default",tc.getNested().getNested().getTestString0()); + assertEquals("deep",tc.getNested().getNested().getTestString1()); + + assertEquals("deep",((TestConfiguration)configuration.getIdMap().get("nestedDeep")).getTestString1()); + assertEquals(2,((TestConfiguration)configuration.getIdMap().get("nestedDeep")).getTestInt2()); + + assertEquals("xxx",tc.getTestString2()); + } + + @Test + public void testNewObject() throws Exception + { + TestConfiguration.VALUE=71; + + URL url = SpringXmlConfigurationTest.class.getClassLoader().getResource(_configure); + XmlConfiguration configuration = new XmlConfiguration(url); + + Map properties = new HashMap(); + properties.put("test", "xxx"); + + TestConfiguration nested = new TestConfiguration(); + nested.setTestString0("nested"); + configuration.getIdMap().put("nested",nested); + + configuration.getProperties().putAll(properties); + TestConfiguration tc = (TestConfiguration)configuration.configure(); + + assertEquals("default",tc.getTestString0()); + assertEquals(-1,tc.getTestInt0()); + assertEquals("SetValue",tc.getTestString1()); + assertEquals(1,tc.getTestInt1()); + + assertEquals("nested",tc.getNested().getTestString0()); + assertEquals("nested",tc.getNested().getTestString1()); + assertEquals("default",tc.getNested().getNested().getTestString0()); + assertEquals("deep",tc.getNested().getNested().getTestString1()); + + assertEquals("deep",((TestConfiguration)configuration.getIdMap().get("nestedDeep")).getTestString1()); + assertEquals(2,((TestConfiguration)configuration.getIdMap().get("nestedDeep")).getTestInt2()); + + assertEquals("xxx",tc.getTestString2()); + } + + @Test + public void testJettyXml() throws Exception + { + URL url = SpringXmlConfigurationTest.class.getClassLoader().getResource("org/mortbay/jetty/spring/jetty.xml"); + XmlConfiguration configuration = new XmlConfiguration(url); + + Server server = (Server)configuration.configure(); + + server.dumpStdErr(); + + } + + @Test + public void XmlConfigurationMain() throws Exception + { + XmlConfiguration.main(new String[]{"src/test/resources/org/mortbay/jetty/spring/jetty.xml"}); + + } +} diff --git a/jetty-spring/src/test/java/org/eclipse/jetty/spring/TestConfiguration.java b/jetty-spring/src/test/java/org/eclipse/jetty/spring/TestConfiguration.java new file mode 100644 index 00000000000..e3300b6096d --- /dev/null +++ b/jetty-spring/src/test/java/org/eclipse/jetty/spring/TestConfiguration.java @@ -0,0 +1,137 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.spring; + +import java.net.URL; + +import org.junit.Ignore; + +@Ignore +public class TestConfiguration +{ + public static int VALUE=77; + + public TestConfiguration nested; + public String testString0="default"; + public String testString1; + public String testString2; + public int testInt0=-1; + public int testInt1; + public int testInt2; + public URL url; + public Object[] objArray; + public int[] intArray; + + + public static int getVALUE() + { + return VALUE; + } + public static void setVALUE(int vALUE) + { + VALUE = vALUE; + } + + public TestConfiguration() + { + } + + public TestConfiguration getNested() + { + return nested; + } + public void setNested(TestConfiguration nested) + { + this.nested = nested; + } + public String getTestString0() + { + return testString0; + } + public void setTestString0(String testString0) + { + this.testString0 = testString0; + } + public String getTestString1() + { + return testString1; + } + public void setTestString1(String testString1) + { + this.testString1 = testString1; + } + public String getTestString2() + { + return testString2; + } + public void setTestString2(String testString2) + { + this.testString2 = testString2; + } + public int getTestInt0() + { + return testInt0; + } + public void setTestInt0(int testInt0) + { + this.testInt0 = testInt0; + } + public int getTestInt1() + { + return testInt1; + } + public void setTestInt1(int testInt1) + { + this.testInt1 = testInt1; + } + public int getTestInt2() + { + return testInt2; + } + public void setTestInt2(int testInt2) + { + this.testInt2 = testInt2; + } + public URL getUrl() + { + return url; + } + public void setUrl(URL url) + { + this.url = url; + } + public Object[] getObjArray() + { + return objArray; + } + public void setObjArray(Object[] objArray) + { + this.objArray = objArray; + } + public int[] getIntArray() + { + return intArray; + } + public void setIntArray(int[] intArray) + { + this.intArray = intArray; + } + + +} diff --git a/jetty-spring/src/test/resources/org/mortbay/jetty/spring/configure.xml b/jetty-spring/src/test/resources/org/mortbay/jetty/spring/configure.xml new file mode 100644 index 00000000000..d55b6453215 --- /dev/null +++ b/jetty-spring/src/test/resources/org/mortbay/jetty/spring/configure.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + get + test + + + + SetValue + 1 + + + + + + 2 + nested + + + + + deep + 2 + + + diff --git a/jetty-spring/src/test/resources/org/mortbay/jetty/spring/jetty-deploy.xml b/jetty-spring/src/test/resources/org/mortbay/jetty/spring/jetty-deploy.xml new file mode 100644 index 00000000000..88258fd1086 --- /dev/null +++ b/jetty-spring/src/test/resources/org/mortbay/jetty/spring/jetty-deploy.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + diff --git a/jetty-spring/src/test/resources/org/mortbay/jetty/spring/jetty.xml b/jetty-spring/src/test/resources/org/mortbay/jetty/spring/jetty.xml new file mode 100644 index 00000000000..cf7dafe16a2 --- /dev/null +++ b/jetty-spring/src/test/resources/org/mortbay/jetty/spring/jetty.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +