diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..29fcbb0 --- /dev/null +++ b/.classpath @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..335c27d --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + tomee-maven-demo + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.maven.ide.eclipse.maven2Builder + + + + + + org.maven.ide.eclipse.maven2Nature + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..fef2bd7 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +#Fri Jan 27 15:43:49 CET 2012 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/.settings/org.maven.ide.eclipse.prefs b/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 0000000..6434337 --- /dev/null +++ b/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,9 @@ +#Tue Jan 31 10:56:54 CET 2012 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=true +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +skipCompilerPlugin=true +version=1 diff --git a/MessageService-soapui-project.xml b/MessageService-soapui-project.xml new file mode 100644 index 0000000..24dfb5e --- /dev/null +++ b/MessageService-soapui-project.xml @@ -0,0 +1,94 @@ + +http://localhost:8081/tomee-maven-demo-war-2.0.0/services/MessageService?wsdl + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]>http://schemas.xmlsoap.org/wsdl/http://localhost:8081/tomee-maven-demo-war-2.0.0/services/MessageServiceUTF-8http://localhost:8081/tomee-maven-demo-war-2.0.0/services/MessageService + + + + + + ? + ? + ? + + + +]]><xml-fragment/>UTF-8http://localhost:8081/tomee-maven-demo-war-2.0.0/services/MessageService + + + + + + Hello David + + + +]]>falseSEQUENCEResponse 1 \ No newline at end of file diff --git a/ear/pom.xml b/ear/pom.xml new file mode 100644 index 0000000..7437480 --- /dev/null +++ b/ear/pom.xml @@ -0,0 +1,105 @@ + + + + 4.0.0 + + + be.dabla + tomee-maven-demo + 2.0.0 + + + tomee-maven-demo-ear + ear + tomee-maven-demo-ear + + + + be.dabla + tomee-maven-demo-war + ${project.version} + war + + + be.dabla + tomee-maven-demo-ejb + ${project.version} + ejb + + + be.dabla + tomee-maven-demo-jar + ${project.version} + + + + javax.validation + validation-api + 1.0.0.GA + + + org.hibernate + hibernate-validator + 4.0.2.GA + + + org.slf4j + slf4j-api + 1.6.1 + + + + + + + org.apache.maven.plugins + maven-ear-plugin + 2.6 + + true + APP-INF/lib + tomee-maven-demo-ear + TomEE Maven Demo + 5 + + + ${project.version} + + + + + be.dabla + tomee-maven-demo-war + tomee-maven-demo-context-root + web.xml + + + be.dabla + tomee-maven-demo-ejb + + + javax.activation + activation + true + + + javax.xml.bind + jaxb-api + true + + + com.sun.xml.bind + jaxb-impl + true + + + javax.xml.stream + stax-api + true + + + + + + + \ No newline at end of file diff --git a/ear/src/main/application/META-INF/weblogic-application.xml b/ear/src/main/application/META-INF/weblogic-application.xml new file mode 100644 index 0000000..c3d876f --- /dev/null +++ b/ear/src/main/application/META-INF/weblogic-application.xml @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/ejb/pom.xml b/ejb/pom.xml new file mode 100644 index 0000000..4266ced --- /dev/null +++ b/ejb/pom.xml @@ -0,0 +1,235 @@ + + + + 4.0.0 + + + be.dabla + tomee-maven-demo + 2.0.0 + + + tomee-maven-demo-ejb + ejb + tomee-maven-demo-ejb + + + + be.dabla + tomee-maven-demo-jar + ${project.version} + provided + + + org.eclipse.persistence + eclipselink + 1.1.0 + provided + + + junit + junit + 4.8.2 + test + + + org.apache.derby + derby + 10.4.2.0 + test + + + org.dbunit + dbunit + 2.4.5 + test + + + org.apache.activemq + activemq-core + 5.2.0 + test + + + org.apache.openejb + openejb-cxf + 3.1.4 + test + + + org.hibernate + hibernate-validator + 4.0.2.GA + test + + + org.slf4j + slf4j-api + 1.6.1 + test + + + be.dabla + tomee-maven-demo-jar + ${project.version} + test + tests + + + javax.validation + validation-api + 1.0.0.GA + provided + + + + javax.ejb + ejb-api + 3.0 + provided + + + javaee + javaee-api + 5 + provided + + + + + + + src/test/resources + true + + + + + org.apache.maven.plugins + maven-ejb-plugin + 2.3 + + 3.0 + + + + org.apache.maven.plugins + maven-jar-plugin + + + test-jar + + test-jar + + + + META-INF/*-jar.xml + jndi.properties + logging.properties + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + pertest + -javaagent:${basedir}/target/openejb-javaagent-3.1.4.jar + ${basedir}/target + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + process-resources + + copy + + + + + org.apache.openejb + openejb-javaagent + 3.1.4 + ${project.build.directory} + + + javax + javaee-endorsed-api + 6.0 + jar + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + process-test-resources + + copy-resources + + + ${basedir}/target/test-classes/META-INF + + + src/main/resources/META-INF + + persistence.xml + orm.xml + + + + + + + + + + + + + default + + true + + + + + src/main/resources + true + + + + + + tomcat + + + + src/main/resources + true + + **/*ejb*.xml + + + + + + + \ No newline at end of file diff --git a/ejb/src/main/java/be/dabla/domain/MessageEJB.java b/ejb/src/main/java/be/dabla/domain/MessageEJB.java new file mode 100644 index 0000000..392ebcb --- /dev/null +++ b/ejb/src/main/java/be/dabla/domain/MessageEJB.java @@ -0,0 +1,57 @@ +package be.dabla.domain; + +import java.util.List; + +import javax.ejb.Remote; +import javax.ejb.Stateless; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import be.dabla.model.Message; + +@Stateless(name="MessageEJB",mappedName="MessageEJB") +@Remote(MessageEJBRemote.class) +public class MessageEJB implements MessageEJBLocal { + @PersistenceContext(unitName = "tomee-maven-demo-pu") + protected EntityManager em; + + @Override + public Number count() { + return (Number)em.createQuery("SELECT COUNT(m.id) FROM Message m").getSingleResult(); + } + + @Override + public List findAll(int start, int size) { + return em.createNamedQuery("Message.findAll").setFirstResult(start).setMaxResults(size).getResultList(); + } + + @Override + public Message findById(final Long id) { + return em.find(Message.class, id); + } + + @Override + public Message create(final Message entity) { + if (entity != null) { + em.persist(entity); + } + + return entity; + } + + @Override + public void delete(final Message entity) { + if (entity != null) { + em.remove(em.merge(entity)); + } + } + + @Override + public Message update(final Message entity) { + if (entity != null) { + return em.merge(entity); + } + + return entity; + } +} \ No newline at end of file diff --git a/ejb/src/main/java/be/dabla/domain/MessageMDBSender.java b/ejb/src/main/java/be/dabla/domain/MessageMDBSender.java new file mode 100644 index 0000000..90a35a3 --- /dev/null +++ b/ejb/src/main/java/be/dabla/domain/MessageMDBSender.java @@ -0,0 +1,59 @@ +package be.dabla.domain; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.annotation.Resource; +import javax.ejb.Remote; +import javax.ejb.Stateless; +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.JMSException; +import javax.jms.MessageProducer; +import javax.jms.ObjectMessage; +import javax.jms.Queue; +import javax.jms.Session; + +import be.dabla.model.Message; +import be.dabla.service.handler.Address; + +@Stateless(name="MessageMDBSender",mappedName="MessageMDBSender") +@Remote(MessageMDBSenderRemote.class) +public class MessageMDBSender implements MessageMDBSenderRemote { + public static final int TIME_TO_LIVE = 120000; // set expiration time to 2 minutes + private static final Logger logger = Logger.getLogger(MessageMDBSender.class.getName()); + @Resource(mappedName="jms/tomee-maven-demo-cf") + ConnectionFactory connectionFactory; + @Resource(mappedName="jms/tomee-maven-demo-q") + Queue queue; + + public void sendMessage(final Address address) throws JMSException { + logger.log(Level.INFO, "sendMessage: {0}", address); + + Connection connection = null; + Session session = null; + + try { + connection = connectionFactory.createConnection(); + connection.start(); + session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE); + final MessageProducer producer = session.createProducer(queue); + producer.setTimeToLive(TIME_TO_LIVE); + final ObjectMessage message = session.createObjectMessage(address); + producer.send(message); + + logger.log(Level.FINE, "Message {0} send...", message); + } + finally { + try { + if (session != null) { + session.close(); + } + } finally { + if (connection != null) { + connection.close(); + } + } + } + } +} \ No newline at end of file diff --git a/ejb/src/main/java/be/dabla/mdb/MessageMDB.java b/ejb/src/main/java/be/dabla/mdb/MessageMDB.java new file mode 100644 index 0000000..761cf29 --- /dev/null +++ b/ejb/src/main/java/be/dabla/mdb/MessageMDB.java @@ -0,0 +1,80 @@ +package be.dabla.mdb; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.EJB; +import javax.ejb.MessageDriven; +import javax.jms.MessageListener; +import javax.jms.ObjectMessage; +import javax.xml.ws.BindingProvider; +import javax.xml.ws.handler.Handler; +import javax.xml.ws.soap.SOAPFaultException; + +import be.dabla.domain.MessageEJBRemote; +import be.dabla.model.Message; +import be.dabla.service.MessageService; +import be.dabla.service.MessageServiceClient; +import be.dabla.service.handler.Address; +import be.dabla.service.handler.WSAddressingClientHandler; + +// http://download.oracle.com/javaee/6/tutorial/doc/gipvi.html (jee6/ejb3.1 would make it a lot easier) +@MessageDriven(mappedName = "jms/tomee-maven-demo-q", activationConfig = { + @ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Queue"), + @ActivationConfigProperty(propertyName="destination",propertyValue="jms/tomee-maven-demo-q") +}) +public class MessageMDB implements MessageListener { + private static final Logger logger = Logger.getLogger(MessageMDB.class.getName()); + final WSAddressingClientHandler handler; + final MessageService port; + + public MessageMDB() { + handler = new WSAddressingClientHandler(); + final List handlerChain = new ArrayList(); + handlerChain.add(handler); + + port = new MessageServiceClient().getMessageService(); + ((BindingProvider)port).getBinding().setHandlerChain(handlerChain); + } + + @EJB + MessageEJBRemote ejb; + + @Override + public void onMessage(final javax.jms.Message msg) { + logger.log(Level.INFO, "onMessage: {0}", msg); + + try { + final Address address = (Address)((ObjectMessage)msg).getObject(); + + logger.log(Level.FINE, "address: {0}", address); + + if (address != null) { + final Message message = ejb.create(address.getContent()); + + logger.log(Level.FINE, "message: {0}", message); + + if (message != null) { + handler.setAddress(address); + ((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, address.getReplyTo()); + port.callbackMessage(message); + + logger.log(Level.INFO, "Message with id {0} acknowledged...", message.getId()); + } + else { + throw new Exception("Address doesn't contain a message!"); + } + } + } + catch(SOAPFaultException e) { + logger.warning(e.toString()); + } + catch(Exception e) { + logger.severe(e.toString()); + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/ejb/src/main/resources/META-INF/ejb-jar.xml b/ejb/src/main/resources/META-INF/ejb-jar.xml new file mode 100644 index 0000000..446dae7 --- /dev/null +++ b/ejb/src/main/resources/META-INF/ejb-jar.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/ejb/src/main/resources/META-INF/weblogic-ejb-jar.xml b/ejb/src/main/resources/META-INF/weblogic-ejb-jar.xml new file mode 100644 index 0000000..60348a5 --- /dev/null +++ b/ejb/src/main/resources/META-INF/weblogic-ejb-jar.xml @@ -0,0 +1,35 @@ + + + + MessageEJB + + + be.dabla.domain.MessageEJBRemote + MessageEJB + + + true + + + MessageMDBSender + + + be.dabla.domain.MessageMDBSenderRemote + MessageMDBSender + + + true + + + MessageMDB + + + 1 + 1 + + jms/tomee-maven-demo-q + jms/tomee-maven-demo-cf + + + \ No newline at end of file diff --git a/ejb/src/test/java/be/dabla/domain/MessageEJBTest.java b/ejb/src/test/java/be/dabla/domain/MessageEJBTest.java new file mode 100644 index 0000000..97416f5 --- /dev/null +++ b/ejb/src/test/java/be/dabla/domain/MessageEJBTest.java @@ -0,0 +1,49 @@ +package be.dabla.domain; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import javax.ejb.EJB; +import javax.naming.NamingException; + +import org.apache.openejb.OpenEJBTestCase; +import org.apache.openejb.api.LocalClient; +import org.junit.Test; + +import be.dabla.domain.MessageEJB; +import be.dabla.domain.MessageEJBRemote; +import be.dabla.model.Message; + +@LocalClient +public class MessageEJBTest extends OpenEJBTestCase { + @EJB + private MessageEJBRemote ejb; + + @Test + public void testCreate() { + assertNull(ejb.create(null)); + + try { + ejb.create(new Message()); // NOT NULL + fail("org.eclipse.persistence.exceptions.DatabaseException"); + } + catch(Exception e) { + + } + + assertNotNull(ejb.create(new Message("Hello World"))); + assertNotNull(ejb.create(new Message("Hello David"))); + } + + @Test + public void testCount() throws NamingException { + assertNotNull(ejb.count()); + } + + @Test + public void testFindAll() throws NamingException { + assertNotNull(initialContext.lookup(MessageEJB.class.getSimpleName())); + assertNotNull(ejb.findAll(0, 10)); + } +} \ No newline at end of file diff --git a/ejb/src/test/java/org/apache/openejb/ClassLoaderUtil.java b/ejb/src/test/java/org/apache/openejb/ClassLoaderUtil.java new file mode 100644 index 0000000..f1c4adb --- /dev/null +++ b/ejb/src/test/java/org/apache/openejb/ClassLoaderUtil.java @@ -0,0 +1,264 @@ +/** + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.openejb; + +import java.beans.Introspector; +import java.io.File; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamClass; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.jar.JarFile; + +import org.apache.openejb.core.TempClassLoader; +import org.apache.openejb.util.LogCategory; +import org.apache.openejb.util.Logger; +import org.apache.openejb.util.UrlCache; + +/** + * @version $Revision: 948987 $ $Date: 2010-05-27 13:55:12 -0700 (Thu, 27 May 2010) $ + */ +public class ClassLoaderUtil { + private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB, ClassLoaderUtil.class); + private static final Map> classLoadersByApp = new HashMap>(); + private static final Map> appsByClassLoader = new HashMap>(); + + private static final UrlCache urlCache = new UrlCache(); + + public static ClassLoader getContextClassLoader() { + return AccessController.doPrivileged(new PrivilegedAction() { + public ClassLoader run() { + return Thread.currentThread().getContextClassLoader(); + } + }); + } + + public static URLClassLoader createClassLoader(String appId, URL[] urls, ClassLoader parent) { + urls = urlCache.cacheUrls(appId, urls); + URLClassLoader classLoader = new URLClassLoader(urls, parent); + + List classLoaders = classLoadersByApp.get(appId); + if (classLoaders == null) { + classLoaders = new ArrayList(2); + classLoadersByApp.put(appId, classLoaders); + } + classLoaders.add(classLoader); + + Set apps = appsByClassLoader.get(classLoader); + if (apps == null) { + apps = new LinkedHashSet(1); + appsByClassLoader.put(classLoader, apps); + } + apps.add(appId); + + return classLoader; + } + + public static void destroyClassLoader(ClassLoader classLoader) { + logger.debug("Destroying classLoader " + toString(classLoader)); + + // remove from the indexes + Set apps = appsByClassLoader.remove(classLoader); + if (apps != null) { + for (String appId : apps) { + List classLoaders = classLoadersByApp.get(appId); + if (classLoaders != null) { + classLoaders.remove(classLoader); + // if this is the last class loader in the app, clean up the app + if (classLoaders.isEmpty()) { + destroyClassLoader(appId); + } + } + } + } + + // clear the lame openjpa caches + cleanOpenJPACache(classLoader); + } + + public static void destroyClassLoader(String appId) { + logger.debug("Destroying classLoaders for application " + appId); + + List classLoaders = classLoadersByApp.remove(appId); + if (classLoaders != null) { + for (ClassLoader classLoader : classLoaders) { + // get the apps using the class loader + Set apps = appsByClassLoader.get(classLoader); + if (apps == null) apps = Collections.emptySet(); + + // this app is no longer using the class loader + apps.remove(appId); + + // if no apps are using the class loader, destroy it + if (apps.isEmpty()) { + appsByClassLoader.remove(classLoader); + destroyClassLoader(classLoader); + } else { + logger.debug("ClassLoader " + toString(classLoader) + " held open by the applications" + apps); + } + } + } + urlCache.releaseUrls(appId); + clearSunJarFileFactoryCache(appId); + } + + public static URLClassLoader createTempClassLoader(ClassLoader parent) { + return new TempClassLoader(parent); + } + + public static URLClassLoader createTempClassLoader(String appId, URL[] urls, ClassLoader parent) { + URLClassLoader classLoader = createClassLoader(appId, urls, parent); + TempClassLoader tempClassLoader = new TempClassLoader(classLoader); + return tempClassLoader; + } + + /** + * Cleans well known class loader leaks in VMs and libraries. There is a lot of bad code out there and this method + * will clear up the know problems. This method should only be called when the class loader will no longer be used. + * It this method is called two often it can have a serious impact on preformance. + */ + public static void clearClassLoaderCaches() { + clearSunSoftCache(ObjectInputStream.class, "subclassAudits"); + clearSunSoftCache(ObjectOutputStream.class, "subclassAudits"); + clearSunSoftCache(ObjectStreamClass.class, "localDescs"); + clearSunSoftCache(ObjectStreamClass.class, "reflectors"); + Introspector.flushCaches(); + } + + public static void clearSunJarFileFactoryCache(final String jarLocation) { + clearSunJarFileFactoryCacheImpl(jarLocation, 5); + } + + private static void clearSunJarFileFactoryCacheImpl(final String jarLocation, final int attempt) { + logger.debug("Clearing Sun JarFileFactory cache for directory " + jarLocation); + + try { + Class jarFileFactory = Class.forName("sun.net.www.protocol.jar.JarFileFactory"); + + synchronized (jarFileFactory) { + + Field fileCacheField = jarFileFactory.getDeclaredField("fileCache"); + + fileCacheField.setAccessible(true); + Map fileCache = (Map) fileCacheField.get(null); + + Field urlCacheField = jarFileFactory.getDeclaredField("urlCache"); + urlCacheField.setAccessible(true); + + Map ucf = (Map) urlCacheField.get(null); + + List removedKeys = new ArrayList(); + for (Map.Entry entry : fileCache.entrySet()) { + if (isParent(jarLocation, new File(entry.getValue().getName()))) { + removedKeys.add(entry.getKey()); + } + } + + for(Object key : removedKeys) { + JarFile jarFile = fileCache.remove(key); + if(jarFile != null) { + ucf.remove(jarFile); + try { + jarFile.close(); + } catch (Throwable e) { + //Ignore + } + } + } + } + } catch (ConcurrentModificationException e) { + if (attempt > 0) { + clearSunJarFileFactoryCacheImpl(jarLocation, (attempt - 1)); + } else { + logger.error("Unable to clear Sun JarFileFactory cache after 5 attempts", e); + } + } catch (ClassNotFoundException e) { + // not a sun vm + } catch (NoSuchFieldException e) { + // different version of sun vm? + } catch (Throwable e) { + logger.error("Unable to clear Sun JarFileFactory cache", e); + } + } + + private static boolean isParent(String jarLocation, File file) { + File dir = new File(jarLocation); + while (file != null) { + if (file.equals(dir)) { + return true; + } + file = file.getParentFile(); + } + return false; + } + + /** + * Clears the caches maintained by the SunVM object stream implementation. This method uses reflection and + * setAccessable to obtain access to the Sun cache. The cache is locked with a synchronize monitor and cleared. + * This method completely clears the class loader cache which will impact preformance of object serialization. + * @param clazz the name of the class containing the cache field + * @param fieldName the name of the cache field + */ + public static void clearSunSoftCache(Class clazz, String fieldName) { + Map cache = null; + try { + Field field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + cache = (Map) field.get(null); + } catch (Throwable ignored) { + // there is nothing a user could do about this anyway + } + + if (cache != null) { + synchronized (cache) { + cache.clear(); + } + } + } + + public static void cleanOpenJPACache(ClassLoader classLoader) { + try { + Class pcRegistryClass = ClassLoaderUtil.class.getClassLoader().loadClass("org.apache.openjpa.enhance.PCRegistry"); + Method deRegisterMethod = pcRegistryClass.getMethod("deRegister", ClassLoader.class); + deRegisterMethod.invoke(null, classLoader); + } catch (Throwable ignored) { + // there is nothing a user could do about this anyway + } + } + + private static String toString(ClassLoader classLoader) { + if (classLoader == null) { + return "null"; + } else { + return classLoader.getClass().getSimpleName() + "@" + System.identityHashCode(classLoader); + } + } +} \ No newline at end of file diff --git a/ejb/src/test/java/org/apache/openejb/OpenEJBTestCase.java b/ejb/src/test/java/org/apache/openejb/OpenEJBTestCase.java new file mode 100644 index 0000000..1a53d82 --- /dev/null +++ b/ejb/src/test/java/org/apache/openejb/OpenEJBTestCase.java @@ -0,0 +1,42 @@ +package org.apache.openejb; + +import java.util.Properties; + +import javax.naming.InitialContext; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.transaction.UserTransaction; + +import org.dbunit.DBUnitFixtureLoader; +import org.junit.After; +import org.junit.Before; + +public abstract class OpenEJBTestCase { + protected static final InitialContext initialContext; + + @PersistenceContext(unitName = "tomee-maven-demo-pu") + protected EntityManager em; + + static { + final Properties properties = new Properties(); + + try { + properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("jndi.properties")); + initialContext = new InitialContext(properties); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Before + public void setUp() throws Exception { + initialContext.bind("inject", this); + + new DBUnitFixtureLoader((UserTransaction)initialContext.lookup("java:comp/UserTransaction"), em).load(); + } + + @After + public void tearDown() throws Exception { + initialContext.unbind("inject"); + } +} \ No newline at end of file diff --git a/ejb/src/test/java/org/dbunit/DBUnitFixtureLoader.java b/ejb/src/test/java/org/dbunit/DBUnitFixtureLoader.java new file mode 100644 index 0000000..b7c3889 --- /dev/null +++ b/ejb/src/test/java/org/dbunit/DBUnitFixtureLoader.java @@ -0,0 +1,121 @@ +package org.dbunit; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringReader; + +import java.security.CodeSource; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import javax.persistence.EntityManager; +import javax.transaction.UserTransaction; + +import org.dbunit.database.DatabaseConnection; +import org.dbunit.dataset.DataSetException; +import org.dbunit.dataset.ReplacementDataSet; +import org.dbunit.dataset.xml.FlatXmlDataSet; +import org.dbunit.operation.DatabaseOperation; +import org.eclipse.persistence.internal.jpa.EntityManagerImpl; +import org.eclipse.persistence.sessions.DatabaseLogin; +import org.eclipse.persistence.sessions.server.ServerSession; +import org.xml.sax.InputSource; + +public class DBUnitFixtureLoader { + + private static final Logger logger = Logger.getLogger(DBUnitFixtureLoader.class.getName()); + private UserTransaction tx; + private EntityManager em; + + public DBUnitFixtureLoader(final UserTransaction tx, final EntityManager em) { + this.tx = tx; + this.em = em; + } + + public void load() throws Exception { + if (tx != null) { + try { + tx.begin(); //start a new transaction + + // http://www.antoniogoncalves.org/xwiki/bin/view/Article/TestingJPA + // http://forums.oracle.com/forums/thread.jspa?threadID=525646 + final ServerSession session = ((EntityManagerImpl) (em.getDelegate())).getServerSession(); + final DatabaseLogin login = session.getLogin(); + final Connection connection = (Connection) login.connectToDatasource(session.getAccessor(), session); + + try { + final Properties properties = new Properties(); + properties.load(getClass().getClassLoader().getResourceAsStream("fixtures")); + + if (!properties.isEmpty()){ + for (final Object resource : properties.keySet()) { + final String name = "fixtures/" + resource; + logger.log(Level.INFO, "Adding fixture ''{0}''", name); + + append(connection, new FlatXmlDataSet(getClass().getClassLoader().getResourceAsStream(name))); + } + } + } + catch(NullPointerException e) { + final CodeSource src = getClass().getProtectionDomain().getCodeSource(); + + System.out.println("CodeSource: " + src); + + if (src != null) { + ZipInputStream zip = null; + ZipEntry entry = null; + + try { + zip = new ZipInputStream(src.getLocation().openStream()); + + // + // Read each entry from the ZipInputStream until no more entry found + // indicated by a null return value of the getNextEntry() method. + // + while ((entry = zip.getNextEntry()) != null) { + if (!entry.isDirectory() && (entry.getName().indexOf("fixture") > -1) && entry.getName().endsWith(".xml")) { + logger.log(Level.INFO, "Adding fixture ''{0}''", entry.getName()); + int size; + final byte[] buffer = new byte[2048]; + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + while ((size = zip.read(buffer, 0, buffer.length)) != -1) { + bos.write(buffer, 0, size); + } + + bos.flush(); + bos.close(); + + append(connection, new FlatXmlDataSet(new StringReader(new String(bos.toByteArray()).trim()))); + } + } + } finally { + if (zip != null) { + zip.close(); + } + } + } + } + } finally { + tx.commit(); + } + } + } + + private void append(final Connection connection, final FlatXmlDataSet xmlDataSet) throws DatabaseUnitException, SQLException { + final DatabaseConnection databaseConnection = new DatabaseConnection(connection); + final ReplacementDataSet dataSet = new ReplacementDataSet(xmlDataSet); + dataSet.addReplacementObject("NULL", null); + + DatabaseOperation.CLEAN_INSERT.execute(databaseConnection, dataSet); + } +} diff --git a/ejb/src/test/resources/META-INF/ejb-jar.xml b/ejb/src/test/resources/META-INF/ejb-jar.xml new file mode 100644 index 0000000..446dae7 --- /dev/null +++ b/ejb/src/test/resources/META-INF/ejb-jar.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/ejb/src/test/resources/fixtures/messages.xml b/ejb/src/test/resources/fixtures/messages.xml new file mode 100644 index 0000000..87b6fbd --- /dev/null +++ b/ejb/src/test/resources/fixtures/messages.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/jar/pom.xml b/jar/pom.xml new file mode 100644 index 0000000..a4554be --- /dev/null +++ b/jar/pom.xml @@ -0,0 +1,107 @@ + + + + 4.0.0 + + + be.dabla + tomee-maven-demo + 2.0.0 + + + tomee-maven-demo-jar + jar + tomee-maven-demo-jar + + + + commons-codec + commons-codec + 1.5 + + + javax.validation + validation-api + 1.0.0.GA + provided + + + javax.ejb + ejb-api + 3.0 + provided + + + junit + junit + 4.8.2 + test + + + org.hibernate + hibernate-validator + 4.0.2.GA + test + + + org.slf4j + slf4j-api + 1.6.1 + test + + + javaee + javaee-api + 5 + provided + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + + + + + default + + true + + + + + src/main/resources + true + + + + + + tomcat + + + + src/main/resources + true + + **/persistence.xml + **/orm.xml + + + + + + + \ No newline at end of file diff --git a/jar/src/main/java/be/dabla/domain/EJBLocal.java b/jar/src/main/java/be/dabla/domain/EJBLocal.java new file mode 100644 index 0000000..0550eeb --- /dev/null +++ b/jar/src/main/java/be/dabla/domain/EJBLocal.java @@ -0,0 +1,11 @@ +package be.dabla.domain; + +import java.util.List; + +import javax.ejb.Local; + +@Local +public interface EJBLocal { + public Number count(); + public List findAll(int start, int size); +} \ No newline at end of file diff --git a/jar/src/main/java/be/dabla/domain/MessageEJBLocal.java b/jar/src/main/java/be/dabla/domain/MessageEJBLocal.java new file mode 100644 index 0000000..38e092c --- /dev/null +++ b/jar/src/main/java/be/dabla/domain/MessageEJBLocal.java @@ -0,0 +1,13 @@ +package be.dabla.domain; + +import javax.ejb.Local; + +import be.dabla.model.Message; + +@Local +public interface MessageEJBLocal extends EJBLocal { + public Message findById(final Long id); + public Message create(final Message entity); + public void delete(final Message Message); + public Message update(final Message entity); +} \ No newline at end of file diff --git a/jar/src/main/java/be/dabla/domain/MessageEJBRemote.java b/jar/src/main/java/be/dabla/domain/MessageEJBRemote.java new file mode 100644 index 0000000..1878aab --- /dev/null +++ b/jar/src/main/java/be/dabla/domain/MessageEJBRemote.java @@ -0,0 +1,8 @@ +package be.dabla.domain; + +import javax.ejb.Remote; + +@Remote +public interface MessageEJBRemote extends MessageEJBLocal { + +} \ No newline at end of file diff --git a/jar/src/main/java/be/dabla/domain/MessageMDBSenderLocal.java b/jar/src/main/java/be/dabla/domain/MessageMDBSenderLocal.java new file mode 100644 index 0000000..d151d28 --- /dev/null +++ b/jar/src/main/java/be/dabla/domain/MessageMDBSenderLocal.java @@ -0,0 +1,12 @@ +package be.dabla.domain; + +import javax.ejb.Local; +import javax.jms.JMSException; + +import be.dabla.model.Message; +import be.dabla.service.handler.Address; + +@Local +public interface MessageMDBSenderLocal { + public void sendMessage(final Address address) throws JMSException; +} \ No newline at end of file diff --git a/jar/src/main/java/be/dabla/domain/MessageMDBSenderRemote.java b/jar/src/main/java/be/dabla/domain/MessageMDBSenderRemote.java new file mode 100644 index 0000000..10fd2c3 --- /dev/null +++ b/jar/src/main/java/be/dabla/domain/MessageMDBSenderRemote.java @@ -0,0 +1,8 @@ +package be.dabla.domain; + +import javax.ejb.Remote; + +@Remote +public interface MessageMDBSenderRemote extends MessageMDBSenderLocal { + +} \ No newline at end of file diff --git a/jar/src/main/java/be/dabla/model/Message.java b/jar/src/main/java/be/dabla/model/Message.java new file mode 100644 index 0000000..d27c4a1 --- /dev/null +++ b/jar/src/main/java/be/dabla/model/Message.java @@ -0,0 +1,89 @@ +package be.dabla.model; + +import java.io.Serializable; +import java.util.Date; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; + +@XmlAccessorType(XmlAccessType.NONE) +public class Message implements Serializable { + @XmlElement + private Long id; + @XmlElement(required = true) + private String description; + @XmlElement + private Date date; + + public Message() { + this(null); + } + + public Message(final String description) { + this.description = description; + this.date = new Date(); + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((date == null) ? 0 : date.hashCode()); + result = prime * result + + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Message other = (Message) obj; + if (date == null) { + if (other.date != null) + return false; + } else if (!date.equals(other.date)) + return false; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } +} \ No newline at end of file diff --git a/jar/src/main/java/be/dabla/model/validation/EntityTraversableResolver.java b/jar/src/main/java/be/dabla/model/validation/EntityTraversableResolver.java new file mode 100644 index 0000000..ab0f593 --- /dev/null +++ b/jar/src/main/java/be/dabla/model/validation/EntityTraversableResolver.java @@ -0,0 +1,16 @@ +package be.dabla.model.validation; + +import java.lang.annotation.ElementType; + +import javax.validation.Path; +import javax.validation.TraversableResolver; + +public class EntityTraversableResolver implements TraversableResolver { + public boolean isReachable(final Object traversableObject, final Path.Node traversableProperty, final Class rootBeanType, final Path pathToTraversableObject, final ElementType elementType) { + return (traversableObject != null); + } + + public boolean isCascadable(final Object traversableObject, final Path.Node traversableProperty, final Class rootBeanType, final Path pathToTraversableObject, final ElementType elementType) { + return true; + } +} \ No newline at end of file diff --git a/jar/src/main/java/be/dabla/model/validation/EntityValidationEventListener.java b/jar/src/main/java/be/dabla/model/validation/EntityValidationEventListener.java new file mode 100644 index 0000000..11ecdd0 --- /dev/null +++ b/jar/src/main/java/be/dabla/model/validation/EntityValidationEventListener.java @@ -0,0 +1,37 @@ +package be.dabla.model.validation; + +import java.util.HashSet; +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.TraversableResolver; +import javax.validation.Validation; +import javax.validation.Validator; + +// http://agoncal.wordpress.com/2010/03/03/bean-validation-with-jpa-1-0/ +public class EntityValidationEventListener { + private final TraversableResolver resolver; + private final Validator validator; + + public EntityValidationEventListener() { + resolver = new EntityTraversableResolver(); + validator = Validation.buildDefaultValidatorFactory().usingContext().traversableResolver(resolver).getValidator(); + } + + public void validate(final Object entity) { + final Set> constraintViolations = validator.validate(entity); + + if (!constraintViolations.isEmpty()) { + final Set> propagatedViolations = new HashSet>(constraintViolations.size()); + final Set classNames = new HashSet(); + + for (final ConstraintViolation violation : constraintViolations) { + propagatedViolations.add(violation); + classNames.add(violation.getLeafBean().getClass().getName()); + } + + throw new ConstraintViolationException(new StringBuilder().append("validation failed for classes ").append(classNames).toString(), propagatedViolations); + } + } +} diff --git a/jar/src/main/java/be/dabla/service/MessageService.java b/jar/src/main/java/be/dabla/service/MessageService.java new file mode 100644 index 0000000..61c6173 --- /dev/null +++ b/jar/src/main/java/be/dabla/service/MessageService.java @@ -0,0 +1,21 @@ +package be.dabla.service; + +import javax.jws.Oneway; +import javax.jws.WebMethod; +import javax.jws.WebParam; +import javax.jws.WebService; +import javax.xml.ws.soap.Addressing; + +import be.dabla.model.Message; + +@Addressing +@WebService(targetNamespace = "urn:service.dabla.be") +public interface MessageService { + @WebMethod(action = "create") + @Oneway + public void create(@WebParam(partName = "payload", name = "Message", targetNamespace = "urn:model.dabla.be")final Message payload); + + @WebMethod(action = "callbackMessage") + @Oneway + public void callbackMessage(@WebParam(partName = "payload", name = "Message", targetNamespace = "urn:model.dabla.be")final Message payload); +} \ No newline at end of file diff --git a/jar/src/main/java/be/dabla/service/MessageServiceClient.java b/jar/src/main/java/be/dabla/service/MessageServiceClient.java new file mode 100644 index 0000000..b97a492 --- /dev/null +++ b/jar/src/main/java/be/dabla/service/MessageServiceClient.java @@ -0,0 +1,50 @@ +package be.dabla.service; + +import java.net.URL; + +import javax.xml.namespace.QName; +import javax.xml.ws.Service; +import javax.xml.ws.WebEndpoint; +import javax.xml.ws.WebServiceClient; +import javax.xml.ws.WebServiceFeature; + +@WebServiceClient(name = "MessageService", targetNamespace = "urn:service.dabla.be", wsdlLocation="file:/tomee-maven-demo/war/src/main/resources/wsdl/MessageService.wsdl") +public class MessageServiceClient extends Service { + public final static URL WSDL_LOCATION = Thread.currentThread().getContextClassLoader().getResource("wsdl/MessageService.wsdl"); + public final static QName SERVICE = new QName("urn:service.dabla.be", "MessageService"); + public final static QName PORT = new QName("urn:service.dabla.be", "MessageServicePort"); + + public MessageServiceClient(URL wsdlLocation) { + super(WSDL_LOCATION, SERVICE); + } + + public MessageServiceClient(URL wsdlLocation, QName serviceName) { + super(WSDL_LOCATION, serviceName); + } + + public MessageServiceClient() { + super(WSDL_LOCATION, SERVICE); + } + + /** + * + * @return + * returns MessageService + */ + @WebEndpoint + public MessageService getMessageService() { + return super.getPort(PORT, MessageService.class); + } + + /** + * + * @param features + * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features parameter will have their default values. + * @return + * returns MessageService + */ + @WebEndpoint + public MessageService getMessageService(WebServiceFeature... features) { + return super.getPort(PORT, MessageService.class, features); + } +} \ No newline at end of file diff --git a/jar/src/main/java/be/dabla/service/handler/Address.java b/jar/src/main/java/be/dabla/service/handler/Address.java new file mode 100644 index 0000000..e2e27f2 --- /dev/null +++ b/jar/src/main/java/be/dabla/service/handler/Address.java @@ -0,0 +1,115 @@ +package be.dabla.service.handler; + +import java.io.Serializable; +import java.util.Map; + +public final class Address implements Serializable { + T content; + String messageId; + String to; + String replyTo; + Map parameters; + + public Address(final T content, final String messageId, final String to, final String replyTo) { + this(content, messageId, to, replyTo, null); + } + + public Address(final T content, final String messageId, final String to, final String replyTo, final Map parameters) { + setContent(content); + setMessageId(messageId); + setTo(to); + setReplyTo(replyTo); + setParameters(parameters); + } + + public T getContent() { + return content; + } + + public void setContent(T content) { + this.content = content; + } + + public String getMessageId() { + return messageId; + } + + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public String getReplyTo() { + return replyTo; + } + + public void setReplyTo(String replyTo) { + this.replyTo = replyTo; + } + + public Map getParameters() { + return parameters; + } + + public void setParameters(Map parameters) { + this.parameters = parameters; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((content == null) ? 0 : content.hashCode()); + result = prime * result + + ((messageId == null) ? 0 : messageId.hashCode()); + result = prime * result + + ((parameters == null) ? 0 : parameters.hashCode()); + result = prime * result + ((replyTo == null) ? 0 : replyTo.hashCode()); + result = prime * result + ((to == null) ? 0 : to.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Address other = (Address) obj; + if (content == null) { + if (other.content != null) + return false; + } else if (!content.equals(other.content)) + return false; + if (messageId == null) { + if (other.messageId != null) + return false; + } else if (!messageId.equals(other.messageId)) + return false; + if (parameters == null) { + if (other.parameters != null) + return false; + } else if (!parameters.equals(other.parameters)) + return false; + if (replyTo == null) { + if (other.replyTo != null) + return false; + } else if (!replyTo.equals(other.replyTo)) + return false; + if (to == null) { + if (other.to != null) + return false; + } else if (!to.equals(other.to)) + return false; + return true; + } +} \ No newline at end of file diff --git a/jar/src/main/java/be/dabla/service/handler/WSAddressingClientHandler.java b/jar/src/main/java/be/dabla/service/handler/WSAddressingClientHandler.java new file mode 100644 index 0000000..2fdf44a --- /dev/null +++ b/jar/src/main/java/be/dabla/service/handler/WSAddressingClientHandler.java @@ -0,0 +1,76 @@ +package be.dabla.service.handler; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.namespace.QName; +import javax.xml.soap.SOAPHeader; +import javax.xml.soap.SOAPHeaderElement; +import javax.xml.ws.handler.MessageContext; +import javax.xml.ws.handler.soap.SOAPHandler; +import javax.xml.ws.handler.soap.SOAPMessageContext; + +public class WSAddressingClientHandler implements SOAPHandler { + static final Logger logger = Logger.getLogger(WSAddressingClientHandler.class.getName()); + Address address = null; + + public Address getAddress() { + return address; + } + + public void setAddress(final Address address) { + this.address = address; + } + + public Set getHeaders() { + return null; + } + + public boolean handleMessage(final SOAPMessageContext context) { + final Boolean outboundProperty = (Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); + + logger.log(Level.FINE, "outboundProperty: {0}", outboundProperty); + + if (outboundProperty.booleanValue() && (getAddress() != null)) { + try { + SOAPHeader header = context.getMessage().getSOAPHeader(); + + if(header == null) { + header = context.getMessage().getSOAPPart().getEnvelope().addHeader(); + } + + header.addHeaderElement(new QName("http://www.w3.org/2005/08/addressing","RelatesTo")).addTextNode(address.getMessageId()); + + logger.log(Level.FINE, "parameters: {0}", getAddress().getParameters()); + + if (getAddress().getParameters() != null) { + final SOAPHeaderElement element = header.addHeaderElement(new QName("http://www.w3.org/2005/08/addressing","ReferenceParameters")); + final Iterator> i = getAddress().getParameters().entrySet().iterator(); + + while(i.hasNext()) { + final Map.Entry entry = i.next(); + + logger.log(Level.FINE, "entry: {0}", entry); + + element.addChildElement(new QName("http://xmlns.oracle.com/sca/tracking/1.0",entry.getKey())).addTextNode(entry.getValue()); + } + } + } catch (Exception e) { + logger.warning(e.getMessage()); + } + } + + return true; + } + + public boolean handleFault(final SOAPMessageContext smc) { + return true; + } + + public void close(final MessageContext messageContext) { + setAddress(null); + } +} \ No newline at end of file diff --git a/jar/src/main/resources/META-INF/orm.xml b/jar/src/main/resources/META-INF/orm.xml new file mode 100644 index 0000000..dc6e18d --- /dev/null +++ b/jar/src/main/resources/META-INF/orm.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TIMESTAMP + + + + \ No newline at end of file diff --git a/jar/src/main/resources/META-INF/persistence.xml b/jar/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000..be6b63f --- /dev/null +++ b/jar/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,14 @@ + + + + org.eclipse.persistence.jpa.PersistenceProvider + jdbc/tomee-maven-demo-ds + + + + + + + + \ No newline at end of file diff --git a/jar/src/test/java/be/dabla/model/MessageTest.java b/jar/src/test/java/be/dabla/model/MessageTest.java new file mode 100644 index 0000000..1ec5dfa --- /dev/null +++ b/jar/src/test/java/be/dabla/model/MessageTest.java @@ -0,0 +1,24 @@ +package be.dabla.model; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import be.dabla.model.Message; + +public class MessageTest { + @Test + public void testEquals() throws Exception { + final Message request = new Message(); + + request.hashCode(); + assertFalse(request.equals(null)); + assertTrue(request.equals(request)); + assertTrue(request.equals(new Message())); + + request.setDescription(""); + assertNotNull(request.getDescription()); + } +} \ No newline at end of file diff --git a/jar/src/test/java/be/dabla/service/MockMessageContext.java b/jar/src/test/java/be/dabla/service/MockMessageContext.java new file mode 100644 index 0000000..2b1da17 --- /dev/null +++ b/jar/src/test/java/be/dabla/service/MockMessageContext.java @@ -0,0 +1,91 @@ +package be.dabla.service; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import javax.xml.ws.handler.MessageContext; + +public class MockMessageContext implements MessageContext { + private Map map; + + public MockMessageContext() { + map = new HashMap(); + map.put("com.sun.xml.ws.api.addressing.messageId", "uuid:" + UUID.randomUUID()); + map.put("com.sun.xml.ws.api.addressing.to", "http://localhost:7001/bc-core-utils-bc1-sync-context-root/UserService"); + map.put("com.sun.xml.ws.addressing.WsaPropertyBag.ReplyToFromRequest", "http://localhost:9999/UserMockService"); + } + + @Override + public Scope getScope(String name) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setScope(String name, Scope scope) { + // TODO Auto-generated method stub + } + + @Override + public void clear() { + map.clear(); + } + + @Override + public boolean containsKey(Object key) { + return map.containsKey(key); + } + + @Override + public boolean containsValue(Object value) { + return map.containsValue(value); + } + + @Override + public Set> entrySet() { + return map.entrySet(); + } + + @Override + public Object get(Object key) { + return map.get(key); + } + + @Override + public boolean isEmpty() { + return map.isEmpty(); + } + + @Override + public Set keySet() { + return map.keySet(); + } + + @Override + public Object put(String key, Object value) { + return map.put(key, value); + } + + @Override + public void putAll(Map m) { + map.putAll(m); + } + + @Override + public Object remove(Object key) { + return map.remove(key); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public Collection values() { + return map.values(); + } +} \ No newline at end of file diff --git a/jar/src/test/java/be/dabla/service/MockSOAPMessageContext.java b/jar/src/test/java/be/dabla/service/MockSOAPMessageContext.java new file mode 100644 index 0000000..4757390 --- /dev/null +++ b/jar/src/test/java/be/dabla/service/MockSOAPMessageContext.java @@ -0,0 +1,43 @@ +package be.dabla.service; + +import java.util.Set; + +import javax.xml.bind.JAXBContext; +import javax.xml.namespace.QName; +import javax.xml.soap.MessageFactory; +import javax.xml.soap.SOAPException; +import javax.xml.soap.SOAPMessage; +import javax.xml.ws.handler.MessageContext; +import javax.xml.ws.handler.soap.SOAPMessageContext; + + +public class MockSOAPMessageContext extends MockMessageContext implements SOAPMessageContext { + SOAPMessage message = null; + + public MockSOAPMessageContext() throws SOAPException { + super(); + + put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, Boolean.valueOf(false)); + setMessage(MessageFactory.newInstance().createMessage()); + } + + @Override + public Object[] getHeaders(QName header, JAXBContext context, boolean allRoles) { + return null; + } + + @Override + public SOAPMessage getMessage() { + return message; + } + + @Override + public Set getRoles() { + return null; + } + + @Override + public void setMessage(SOAPMessage message) { + this.message = message; + } +} \ No newline at end of file diff --git a/jar/src/test/java/be/dabla/service/handler/AddressTest.java b/jar/src/test/java/be/dabla/service/handler/AddressTest.java new file mode 100644 index 0000000..3b4b34b --- /dev/null +++ b/jar/src/test/java/be/dabla/service/handler/AddressTest.java @@ -0,0 +1,29 @@ +package be.dabla.service.handler; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import be.dabla.model.Message; +import be.dabla.service.handler.Address; + +public class AddressTest { + @Test + public void testAddress() { + final Address address = MockAddress.mock(); + assertEquals(address.getContent(), MockAddress.MESSAGE); + assertEquals(address.getMessageId(), MockAddress.MESSAGE_ID); + assertEquals(address.getTo(), MockAddress.ADDRESS); + assertEquals(address.getReplyTo(), MockAddress.ADDRESS); + + assertFalse(address.equals(null)); + assertFalse(address.equals(new Address(null, null, null, null))); + assertFalse(address.equals(new Address(MockAddress.MESSAGE, "", "", ""))); + assertTrue(address.equals(address)); + assertTrue(address.equals(MockAddress.mock())); + + address.hashCode(); + } +} \ No newline at end of file diff --git a/jar/src/test/java/be/dabla/service/handler/MockAddress.java b/jar/src/test/java/be/dabla/service/handler/MockAddress.java new file mode 100644 index 0000000..6af9607 --- /dev/null +++ b/jar/src/test/java/be/dabla/service/handler/MockAddress.java @@ -0,0 +1,14 @@ +package be.dabla.service.handler; + +import be.dabla.model.Message; +import be.dabla.service.handler.Address; + +public class MockAddress { + public static final Message MESSAGE = new Message("Hello World"); + public static final String MESSAGE_ID = "uuid:cc633354-97d1-4940-a2a3-9b6d18b1fe81"; + public static final String ADDRESS = "http://www.w3.org/2005/08/addressing/anonymous"; + + public static Address mock() { + return new Address(MESSAGE, MESSAGE_ID, ADDRESS, ADDRESS); + } +} \ No newline at end of file diff --git a/jar/src/test/java/be/dabla/service/handler/WSAddressingClientHandlerTest.java b/jar/src/test/java/be/dabla/service/handler/WSAddressingClientHandlerTest.java new file mode 100644 index 0000000..a1f2ec9 --- /dev/null +++ b/jar/src/test/java/be/dabla/service/handler/WSAddressingClientHandlerTest.java @@ -0,0 +1,35 @@ +package be.dabla.service.handler; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import javax.xml.soap.SOAPException; +import javax.xml.ws.handler.MessageContext; +import javax.xml.ws.handler.soap.SOAPMessageContext; + +import org.junit.Test; + +import be.dabla.service.MockSOAPMessageContext; +import be.dabla.service.handler.WSAddressingClientHandler; + +public class WSAddressingClientHandlerTest { + @Test + public void testHandler() throws SOAPException { + final WSAddressingClientHandler handler = new WSAddressingClientHandler(); + assertNull(handler.getHeaders()); + assertNull(handler.getAddress()); + + final SOAPMessageContext context = new MockSOAPMessageContext(); + handler.handleMessage(context); + context.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, Boolean.valueOf(true)); + handler.handleMessage(context); + handler.setAddress(MockAddress.mock()); + assertNotNull(handler.getAddress()); + handler.handleMessage(context); + context.getMessage().getSOAPPart().getEnvelope().removeChild(context.getMessage().getSOAPHeader()); + handler.handleMessage(context); + + handler.handleFault(context); + handler.close(context); + } +} \ No newline at end of file diff --git a/jar/src/test/resources/jndi.properties b/jar/src/test/resources/jndi.properties new file mode 100644 index 0000000..7e90c95 --- /dev/null +++ b/jar/src/test/resources/jndi.properties @@ -0,0 +1,20 @@ +java.naming.factory.initial=org.apache.openejb.client.LocalInitialContextFactory +openejb.embedded.remotable=true +# following line ignores the weblogic-ejb-jar.xml +openejb.vendor.config=NONE +# http://openejb.apache.org/3.0/configuring-persistenceunits-in-tests.html +jdbc/tomee-maven-demo-ds=new://Resource?type=DataSource +jdbc/tomee-maven-demo-ds.JdbcDriver=org.apache.derby.jdbc.EmbeddedDriver +jdbc/tomee-maven-demo-ds.JdbcUrl=jdbc:derby:derby;create=true +jdbc/tomee-maven-demo-ds.Username=APP +jdbc/tomee-maven-demo-ds.Password=APP +tomee-maven-demo-pu.eclipselink.logging.level=SEVERE +tomee-maven-demo-pu.eclipselink.ddl-generation=drop-and-create-tables +tomee-maven-demo-pu.eclipselink.target-database=org.eclipse.persistence.platform.database.DerbyPlatform + +Default\ JMS\ Resource\ Adapter=new://Resource?type=ActiveMQResourceAdapter +Default\ JMS\ Resource\ Adapter.ServerUrl=tcp://localhost:61616 +Default\ JMS\ Resource\ Adapter.BrokerXmlConfig=broker:(tcp://localhost:61616) +jms/tomee-maven-demo-cf=new://Resource?type=javax.jms.ConnectionFactory +jms/tomee-maven-demo-cf.ResourceAdapter=Default JMS Resource Adapter +jms/tomee-maven-demo-q=new://Resource?type=javax.jms.Queue \ No newline at end of file diff --git a/jar/src/test/resources/logging.properties b/jar/src/test/resources/logging.properties new file mode 100644 index 0000000..d4a07c1 --- /dev/null +++ b/jar/src/test/resources/logging.properties @@ -0,0 +1,34 @@ +# Add handlers to the root logger. +# These are inherited by all other loggers. +handlers=java.util.logging.ConsoleHandler, java.util.logging.FileHandler + +# Configure the ConsoleHandler. +# ConsoleHandler uses java.util.logging.SimpleFormatter by default. +# Even though the root logger has the same level as this, +# the next line is still needed because we're configuring a handler, +# not a logger, and handlers don't inherit properties from the root logger. +java.util.logging.ConsoleHandler.level=FINE + +# Configure the FileHandler. +# FileHandler uses java.util.logging.XMLFormatter by default. +java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter +java.util.logging.FileHandler.level=FINEST + +# The following special tokens can be used in the pattern property +# which specifies the location and name of the log file. +# / - standard path separator +# %t - system temporary directory +# %h - value of the user.home system property +# %g - generation number for rotating logs +# %u - unique number to avoid conflicts +# FileHandler writes to %h/demo0.log by default. +java.util.logging.FileHandler.pattern=target/test.log + +# Set the logging level of the root logger. +# Levels from lowest to highest are +# FINEST, FINER, FINE, CONFIG, INFO, WARNING and SEVERE. +# The default level for all loggers and handlers is INFO. +.level=INFO + +# Specify logging levels for specific namespaces. +be.dabla=FINEST \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..08334f2 --- /dev/null +++ b/pom.xml @@ -0,0 +1,135 @@ + + + + 4.0.0 + + be.dabla + tomee-maven-demo + 2.0.0 + pom + TomEE Maven Demo + + + dablomatique + http://dablomatique.wordpress.com/ + + + + + dabla + David Blain + + developer + + dablomatique@gmail.com + dablomatique + + + + + jar + ejb + war + ear + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.0.2 + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.9 + + once + + + + java.util.logging.config.file + ${build.testOutputDirectory}/logging.properties + + + + + + org.codehaus.mojo + cobertura-maven-plugin + 2.5.1 + + + + + + org.codehaus.mojo + cobertura-maven-plugin + + + + + **/jaxws/*.class + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.1.2 + + + + index + summary + project-team + dependencies + dependency-convergence + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 2.1 + + + org.codehaus.mojo + cobertura-maven-plugin + 2.5.1 + + + + + + + dev + + true + + + Development + jdbc:oracle:thin:@localhost:1521:XE + scott + scott + + + + \ No newline at end of file diff --git a/war/derby/db.lck b/war/derby/db.lck new file mode 100644 index 0000000..f36162a Binary files /dev/null and b/war/derby/db.lck differ diff --git a/war/derby/log/log.ctrl b/war/derby/log/log.ctrl new file mode 100644 index 0000000..da8655b Binary files /dev/null and b/war/derby/log/log.ctrl differ diff --git a/war/derby/log/log1.dat b/war/derby/log/log1.dat new file mode 100644 index 0000000..98a342f Binary files /dev/null and b/war/derby/log/log1.dat differ diff --git a/war/derby/log/logmirror.ctrl b/war/derby/log/logmirror.ctrl new file mode 100644 index 0000000..da8655b Binary files /dev/null and b/war/derby/log/logmirror.ctrl differ diff --git a/war/derby/seg0/c10.dat b/war/derby/seg0/c10.dat new file mode 100644 index 0000000..59c8929 Binary files /dev/null and b/war/derby/seg0/c10.dat differ diff --git a/war/derby/seg0/c101.dat b/war/derby/seg0/c101.dat new file mode 100644 index 0000000..91746f7 Binary files /dev/null and b/war/derby/seg0/c101.dat differ diff --git a/war/derby/seg0/c111.dat b/war/derby/seg0/c111.dat new file mode 100644 index 0000000..5ce79a2 Binary files /dev/null and b/war/derby/seg0/c111.dat differ diff --git a/war/derby/seg0/c121.dat b/war/derby/seg0/c121.dat new file mode 100644 index 0000000..326de97 Binary files /dev/null and b/war/derby/seg0/c121.dat differ diff --git a/war/derby/seg0/c130.dat b/war/derby/seg0/c130.dat new file mode 100644 index 0000000..16099b8 Binary files /dev/null and b/war/derby/seg0/c130.dat differ diff --git a/war/derby/seg0/c141.dat b/war/derby/seg0/c141.dat new file mode 100644 index 0000000..0524a2f Binary files /dev/null and b/war/derby/seg0/c141.dat differ diff --git a/war/derby/seg0/c150.dat b/war/derby/seg0/c150.dat new file mode 100644 index 0000000..93248fd Binary files /dev/null and b/war/derby/seg0/c150.dat differ diff --git a/war/derby/seg0/c161.dat b/war/derby/seg0/c161.dat new file mode 100644 index 0000000..4f7b93d Binary files /dev/null and b/war/derby/seg0/c161.dat differ diff --git a/war/derby/seg0/c171.dat b/war/derby/seg0/c171.dat new file mode 100644 index 0000000..33afae6 Binary files /dev/null and b/war/derby/seg0/c171.dat differ diff --git a/war/derby/seg0/c180.dat b/war/derby/seg0/c180.dat new file mode 100644 index 0000000..e4c005f Binary files /dev/null and b/war/derby/seg0/c180.dat differ diff --git a/war/derby/seg0/c191.dat b/war/derby/seg0/c191.dat new file mode 100644 index 0000000..8c72abf Binary files /dev/null and b/war/derby/seg0/c191.dat differ diff --git a/war/derby/seg0/c1a1.dat b/war/derby/seg0/c1a1.dat new file mode 100644 index 0000000..fbd454f Binary files /dev/null and b/war/derby/seg0/c1a1.dat differ diff --git a/war/derby/seg0/c1b1.dat b/war/derby/seg0/c1b1.dat new file mode 100644 index 0000000..ed5563f Binary files /dev/null and b/war/derby/seg0/c1b1.dat differ diff --git a/war/derby/seg0/c1c0.dat b/war/derby/seg0/c1c0.dat new file mode 100644 index 0000000..c5b91e2 Binary files /dev/null and b/war/derby/seg0/c1c0.dat differ diff --git a/war/derby/seg0/c1d1.dat b/war/derby/seg0/c1d1.dat new file mode 100644 index 0000000..451f02f Binary files /dev/null and b/war/derby/seg0/c1d1.dat differ diff --git a/war/derby/seg0/c1e0.dat b/war/derby/seg0/c1e0.dat new file mode 100644 index 0000000..761408d Binary files /dev/null and b/war/derby/seg0/c1e0.dat differ diff --git a/war/derby/seg0/c1f1.dat b/war/derby/seg0/c1f1.dat new file mode 100644 index 0000000..78d701f Binary files /dev/null and b/war/derby/seg0/c1f1.dat differ diff --git a/war/derby/seg0/c20.dat b/war/derby/seg0/c20.dat new file mode 100644 index 0000000..aa02b13 Binary files /dev/null and b/war/derby/seg0/c20.dat differ diff --git a/war/derby/seg0/c200.dat b/war/derby/seg0/c200.dat new file mode 100644 index 0000000..c3a7808 Binary files /dev/null and b/war/derby/seg0/c200.dat differ diff --git a/war/derby/seg0/c211.dat b/war/derby/seg0/c211.dat new file mode 100644 index 0000000..54e1586 Binary files /dev/null and b/war/derby/seg0/c211.dat differ diff --git a/war/derby/seg0/c221.dat b/war/derby/seg0/c221.dat new file mode 100644 index 0000000..59900bc Binary files /dev/null and b/war/derby/seg0/c221.dat differ diff --git a/war/derby/seg0/c230.dat b/war/derby/seg0/c230.dat new file mode 100644 index 0000000..24afa7b Binary files /dev/null and b/war/derby/seg0/c230.dat differ diff --git a/war/derby/seg0/c241.dat b/war/derby/seg0/c241.dat new file mode 100644 index 0000000..f136593 Binary files /dev/null and b/war/derby/seg0/c241.dat differ diff --git a/war/derby/seg0/c251.dat b/war/derby/seg0/c251.dat new file mode 100644 index 0000000..ec65ace Binary files /dev/null and b/war/derby/seg0/c251.dat differ diff --git a/war/derby/seg0/c260.dat b/war/derby/seg0/c260.dat new file mode 100644 index 0000000..25f81fd Binary files /dev/null and b/war/derby/seg0/c260.dat differ diff --git a/war/derby/seg0/c271.dat b/war/derby/seg0/c271.dat new file mode 100644 index 0000000..51cde57 Binary files /dev/null and b/war/derby/seg0/c271.dat differ diff --git a/war/derby/seg0/c281.dat b/war/derby/seg0/c281.dat new file mode 100644 index 0000000..cfed875 Binary files /dev/null and b/war/derby/seg0/c281.dat differ diff --git a/war/derby/seg0/c290.dat b/war/derby/seg0/c290.dat new file mode 100644 index 0000000..4d10db4 Binary files /dev/null and b/war/derby/seg0/c290.dat differ diff --git a/war/derby/seg0/c2a1.dat b/war/derby/seg0/c2a1.dat new file mode 100644 index 0000000..8e2ed6a Binary files /dev/null and b/war/derby/seg0/c2a1.dat differ diff --git a/war/derby/seg0/c2b1.dat b/war/derby/seg0/c2b1.dat new file mode 100644 index 0000000..2a29692 Binary files /dev/null and b/war/derby/seg0/c2b1.dat differ diff --git a/war/derby/seg0/c2c1.dat b/war/derby/seg0/c2c1.dat new file mode 100644 index 0000000..5511575 Binary files /dev/null and b/war/derby/seg0/c2c1.dat differ diff --git a/war/derby/seg0/c2d0.dat b/war/derby/seg0/c2d0.dat new file mode 100644 index 0000000..4adc6e4 Binary files /dev/null and b/war/derby/seg0/c2d0.dat differ diff --git a/war/derby/seg0/c2e1.dat b/war/derby/seg0/c2e1.dat new file mode 100644 index 0000000..b37b9b2 Binary files /dev/null and b/war/derby/seg0/c2e1.dat differ diff --git a/war/derby/seg0/c2f0.dat b/war/derby/seg0/c2f0.dat new file mode 100644 index 0000000..d854b4b Binary files /dev/null and b/war/derby/seg0/c2f0.dat differ diff --git a/war/derby/seg0/c300.dat b/war/derby/seg0/c300.dat new file mode 100644 index 0000000..2053e01 Binary files /dev/null and b/war/derby/seg0/c300.dat differ diff --git a/war/derby/seg0/c31.dat b/war/derby/seg0/c31.dat new file mode 100644 index 0000000..c89f7af Binary files /dev/null and b/war/derby/seg0/c31.dat differ diff --git a/war/derby/seg0/c311.dat b/war/derby/seg0/c311.dat new file mode 100644 index 0000000..f60c260 Binary files /dev/null and b/war/derby/seg0/c311.dat differ diff --git a/war/derby/seg0/c321.dat b/war/derby/seg0/c321.dat new file mode 100644 index 0000000..a9d7453 Binary files /dev/null and b/war/derby/seg0/c321.dat differ diff --git a/war/derby/seg0/c331.dat b/war/derby/seg0/c331.dat new file mode 100644 index 0000000..85ee72b Binary files /dev/null and b/war/derby/seg0/c331.dat differ diff --git a/war/derby/seg0/c340.dat b/war/derby/seg0/c340.dat new file mode 100644 index 0000000..d99b11a Binary files /dev/null and b/war/derby/seg0/c340.dat differ diff --git a/war/derby/seg0/c351.dat b/war/derby/seg0/c351.dat new file mode 100644 index 0000000..f822f4c Binary files /dev/null and b/war/derby/seg0/c351.dat differ diff --git a/war/derby/seg0/c361.dat b/war/derby/seg0/c361.dat new file mode 100644 index 0000000..b5c8f25 Binary files /dev/null and b/war/derby/seg0/c361.dat differ diff --git a/war/derby/seg0/c371.dat b/war/derby/seg0/c371.dat new file mode 100644 index 0000000..ad11f01 Binary files /dev/null and b/war/derby/seg0/c371.dat differ diff --git a/war/derby/seg0/c380.dat b/war/derby/seg0/c380.dat new file mode 100644 index 0000000..561397e Binary files /dev/null and b/war/derby/seg0/c380.dat differ diff --git a/war/derby/seg0/c391.dat b/war/derby/seg0/c391.dat new file mode 100644 index 0000000..e15720b Binary files /dev/null and b/war/derby/seg0/c391.dat differ diff --git a/war/derby/seg0/c3a1.dat b/war/derby/seg0/c3a1.dat new file mode 100644 index 0000000..02bd17b Binary files /dev/null and b/war/derby/seg0/c3a1.dat differ diff --git a/war/derby/seg0/c3b1.dat b/war/derby/seg0/c3b1.dat new file mode 100644 index 0000000..3804011 Binary files /dev/null and b/war/derby/seg0/c3b1.dat differ diff --git a/war/derby/seg0/c3c0.dat b/war/derby/seg0/c3c0.dat new file mode 100644 index 0000000..4d061cf Binary files /dev/null and b/war/derby/seg0/c3c0.dat differ diff --git a/war/derby/seg0/c3d1.dat b/war/derby/seg0/c3d1.dat new file mode 100644 index 0000000..45c9fa2 Binary files /dev/null and b/war/derby/seg0/c3d1.dat differ diff --git a/war/derby/seg0/c3e1.dat b/war/derby/seg0/c3e1.dat new file mode 100644 index 0000000..48f53e6 Binary files /dev/null and b/war/derby/seg0/c3e1.dat differ diff --git a/war/derby/seg0/c3f1.dat b/war/derby/seg0/c3f1.dat new file mode 100644 index 0000000..08acdce Binary files /dev/null and b/war/derby/seg0/c3f1.dat differ diff --git a/war/derby/seg0/c41.dat b/war/derby/seg0/c41.dat new file mode 100644 index 0000000..697ebcb Binary files /dev/null and b/war/derby/seg0/c41.dat differ diff --git a/war/derby/seg0/c4a0.dat b/war/derby/seg0/c4a0.dat new file mode 100644 index 0000000..de30561 Binary files /dev/null and b/war/derby/seg0/c4a0.dat differ diff --git a/war/derby/seg0/c4b1.dat b/war/derby/seg0/c4b1.dat new file mode 100644 index 0000000..4a0bde2 Binary files /dev/null and b/war/derby/seg0/c4b1.dat differ diff --git a/war/derby/seg0/c51.dat b/war/derby/seg0/c51.dat new file mode 100644 index 0000000..f71c8ad Binary files /dev/null and b/war/derby/seg0/c51.dat differ diff --git a/war/derby/seg0/c60.dat b/war/derby/seg0/c60.dat new file mode 100644 index 0000000..b08b9b5 Binary files /dev/null and b/war/derby/seg0/c60.dat differ diff --git a/war/derby/seg0/c71.dat b/war/derby/seg0/c71.dat new file mode 100644 index 0000000..a4c7b89 Binary files /dev/null and b/war/derby/seg0/c71.dat differ diff --git a/war/derby/seg0/c81.dat b/war/derby/seg0/c81.dat new file mode 100644 index 0000000..88bb79d Binary files /dev/null and b/war/derby/seg0/c81.dat differ diff --git a/war/derby/seg0/c90.dat b/war/derby/seg0/c90.dat new file mode 100644 index 0000000..d78b8b5 Binary files /dev/null and b/war/derby/seg0/c90.dat differ diff --git a/war/derby/seg0/ca1.dat b/war/derby/seg0/ca1.dat new file mode 100644 index 0000000..593fd88 Binary files /dev/null and b/war/derby/seg0/ca1.dat differ diff --git a/war/derby/seg0/cb1.dat b/war/derby/seg0/cb1.dat new file mode 100644 index 0000000..a82f680 Binary files /dev/null and b/war/derby/seg0/cb1.dat differ diff --git a/war/derby/seg0/cc0.dat b/war/derby/seg0/cc0.dat new file mode 100644 index 0000000..2268720 Binary files /dev/null and b/war/derby/seg0/cc0.dat differ diff --git a/war/derby/seg0/cd1.dat b/war/derby/seg0/cd1.dat new file mode 100644 index 0000000..d919a1b Binary files /dev/null and b/war/derby/seg0/cd1.dat differ diff --git a/war/derby/seg0/ce1.dat b/war/derby/seg0/ce1.dat new file mode 100644 index 0000000..299e0c4 Binary files /dev/null and b/war/derby/seg0/ce1.dat differ diff --git a/war/derby/seg0/cf0.dat b/war/derby/seg0/cf0.dat new file mode 100644 index 0000000..04b10fd Binary files /dev/null and b/war/derby/seg0/cf0.dat differ diff --git a/war/derby/seg0/d480.dat b/war/derby/seg0/d480.dat new file mode 100644 index 0000000..bcd2bd9 Binary files /dev/null and b/war/derby/seg0/d480.dat differ diff --git a/war/derby/seg0/d491.dat b/war/derby/seg0/d491.dat new file mode 100644 index 0000000..e2a673b Binary files /dev/null and b/war/derby/seg0/d491.dat differ diff --git a/war/derby/service.properties b/war/derby/service.properties new file mode 100644 index 0000000..d1ac2b1 --- /dev/null +++ b/war/derby/service.properties @@ -0,0 +1,22 @@ +#D:\Work\Projects\tomee-maven-demo\war\derby +# ******************************************************************** +# *** Please do NOT edit this file. *** +# *** CHANGING THE CONTENT OF THIS FILE MAY CAUSE DATA CORRUPTION. *** +# ******************************************************************** +#Tue Jan 31 12:13:41 CET 2012 +SysschemasIndex2Identifier=225 +SyscolumnsIdentifier=144 +SysconglomeratesIndex1Identifier=49 +SysconglomeratesIdentifier=32 +SyscolumnsIndex2Identifier=177 +SysschemasIndex1Identifier=209 +SysconglomeratesIndex3Identifier=81 +SystablesIndex2Identifier=129 +SyscolumnsIndex1Identifier=161 +derby.serviceProtocol=org.apache.derby.database.Database +SysschemasIdentifier=192 +derby.storage.propertiesId=16 +SysconglomeratesIndex2Identifier=65 +derby.serviceLocale=en_US +SystablesIdentifier=96 +SystablesIndex1Identifier=113 diff --git a/war/pom.xml b/war/pom.xml new file mode 100644 index 0000000..faee1a8 --- /dev/null +++ b/war/pom.xml @@ -0,0 +1,443 @@ + + + + 4.0.0 + + + be.dabla + tomee-maven-demo + 2.0.0 + + + tomee-maven-demo-war + war + tomee-maven-demo-war + + + + com.sun.faces + jsf-api + 2.0.6 + + + com.sun.faces + jsf-impl + 2.0.6 + + + javax.servlet + jstl + 1.2 + + + javax.servlet.jsp + jsp-api + 2.1 + test + + + be.dabla + tomee-maven-demo-ejb + ${project.version} + provided + + + be.dabla + tomee-maven-demo-jar + ${project.version} + provided + + + org.eclipse.persistence + eclipselink + 1.1.0 + provided + + + javax.validation + validation-api + 1.0.0.GA + provided + + + javax.ejb + ejb-api + 3.0 + provided + + + be.dabla + tomee-maven-demo-ejb + ${project.version} + test + tests + + + be.dabla + tomee-maven-demo-jar + ${project.version} + test + tests + + + junit + junit + 4.8.2 + test + + + org.apache.derby + derby + 10.4.2.0 + test + + + org.dbunit + dbunit + 2.4.5 + test + + + org.apache.activemq + activemq-core + 5.2.0 + test + + + org.apache.openejb + openejb-cxf + 3.1.4 + test + + + org.apache.cxf + cxf-bundle + + + + + org.hibernate + hibernate-validator + 4.0.2.GA + test + + + org.slf4j + slf4j-api + 1.6.1 + test + + + org.apache.cxf + cxf-bundle + 2.2.10 + provided + + + org.springframework + spring-mock + 2.0.1 + test + + + javaee + javaee-api + 5 + provided + + + + + + + src/main/resources + + **/* + + + + + + + target/classes + + + + target/generated-classes/cobertura + + + src/test/resources + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + derby.stream.error.file + target/derby.log + + + + + + org.codehaus.mojo + jaxws-maven-plugin + + + RequestService + + wsgen + + + src/main/resources/wsdl + be.dabla.service.impl.MessageServiceImpl + true + true + + + + + + javax.ejb + ejb-api + 3.0 + + + javax.jms + jms + 1.1 + + + javax.validation + validation-api + 1.0.0.GA + + + be.dabla + tomee-maven-demo-ejb + ${project.version} + + + be.dabla + tomee-maven-demo-jar + ${project.version} + + + + + org.apache.maven.plugins + maven-resources-plugin + + + prepare-package + + copy-resources + + + ${basedir}/target/classes/wsdl + + + src/main/resources/wsdl + + + + + + + + org.apache.maven.plugins + maven-war-plugin + 2.1.1 + + + + src/main/webapp + true + + + src/main/resources + true + WEB-INF + + **/*.properties + + + + + + + + + + + default + + true + + + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-platform-specific-generated-web-xml-file-to-web-inf-classes + prepare-package + + copy-resources + + + ${basedir}/target/${project.artifactId}-${project.version}/WEB-INF + + + src/main/resources + true + + *.xml + + + + + + + + + + + + tomcat + + + + Web Service Servlet + be.dabla.servlet.CXFServlet + + package + be.dabla.service.impl + + 1 + + ]]> + + + + Web Service Servlet + /services/* + + ]]> + + + + persistence/em + tomee-maven-demo-pu + + ]]> + + + + + be.dabla + tomee-maven-demo-ejb + ${project.version} + + + be.dabla + tomee-maven-demo-jar + ${project.version} + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-env-entry-properties-to-web-inf-classes + prepare-package + + copy-resources + + + ${basedir}/target/${project.artifactId}-${project.version}/WEB-INF/classes + + + src/main/resources + + env-entry.properties + + + + + + + copy-persistence-related-files-from-ejb-and-cxf-servlet-to-web-inf-classes + prepare-package + + copy-resources + + + ${basedir}/target/${project.artifactId}-${project.version}/WEB-INF/classes + + + ../jar/src/main/resources + true + + **/persistence.xml + **/orm.xml + + + + target/test-classes + + **/CXFServlet.class + + + + + + + copy-platform-specific-generated-web-xml-file-to-web-inf-classes + prepare-package + + copy-resources + + + ${basedir}/target/${project.artifactId}-${project.version}/WEB-INF + + + src/main/resources + true + + web.xml + + + + ../ejb/src/main/resources/META-INF + true + + **/ejb-jar.xml + + + + + + + + + + + + \ No newline at end of file diff --git a/war/src/main/java/be/dabla/AbstractInitialContextProvider.java b/war/src/main/java/be/dabla/AbstractInitialContextProvider.java new file mode 100644 index 0000000..4924acb --- /dev/null +++ b/war/src/main/java/be/dabla/AbstractInitialContextProvider.java @@ -0,0 +1,28 @@ +package be.dabla; + +import java.io.InputStream; +import java.io.Serializable; +import java.util.Properties; + +import javax.naming.InitialContext; + + +public abstract class AbstractInitialContextProvider implements Serializable { + protected static final InitialContext initialContext; + + static { + final Properties properties = new Properties(); + + try { + final InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream("env-entry.properties"); + + if (input != null) { + properties.load(input); + } + + initialContext = new InitialContext(properties); + } catch(Exception e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/war/src/main/java/be/dabla/model/AbstractPaginationController.java b/war/src/main/java/be/dabla/model/AbstractPaginationController.java new file mode 100644 index 0000000..93092ea --- /dev/null +++ b/war/src/main/java/be/dabla/model/AbstractPaginationController.java @@ -0,0 +1,15 @@ +package be.dabla.model; + +import be.dabla.AbstractInitialContextProvider; + +public abstract class AbstractPaginationController extends AbstractInitialContextProvider { + final RepeatPaginator paginator; + + protected AbstractPaginationController(final RepeatPaginator paginator) { + this.paginator = paginator; + } + + public RepeatPaginator getPaginator() { + return paginator; + } +} \ No newline at end of file diff --git a/war/src/main/java/be/dabla/model/MessageController.java b/war/src/main/java/be/dabla/model/MessageController.java new file mode 100644 index 0000000..ffcafb9 --- /dev/null +++ b/war/src/main/java/be/dabla/model/MessageController.java @@ -0,0 +1,13 @@ +package be.dabla.model; + +import javax.naming.NamingException; + +import be.dabla.domain.MessageEJB; +import be.dabla.domain.MessageEJBRemote; +import be.dabla.model.Message; + +public class MessageController extends AbstractPaginationController { + public MessageController() throws NamingException { + super(new RepeatPaginator((MessageEJBRemote)initialContext.lookup(MessageEJB.class.getSimpleName()))); + } +} \ No newline at end of file diff --git a/war/src/main/java/be/dabla/model/RepeatPaginator.java b/war/src/main/java/be/dabla/model/RepeatPaginator.java new file mode 100644 index 0000000..e5d8eea --- /dev/null +++ b/war/src/main/java/be/dabla/model/RepeatPaginator.java @@ -0,0 +1,99 @@ +package be.dabla.model; + +import java.util.List; + +import be.dabla.domain.EJBLocal; + +public class RepeatPaginator { + private static final int DEFAULT_RECORDS_NUMBER = 50; + private static final int DEFAULT_PAGE_INDEX = 1; + + final EJBLocal ejb; + int records = DEFAULT_RECORDS_NUMBER; + int recordsTotal; + int pageIndex = DEFAULT_PAGE_INDEX; + int pages; + List model; + + public RepeatPaginator(final EJBLocal ejb) { + this.ejb = ejb; + + updateModel(); + } + + public void updateModel() { + this.recordsTotal = ejb.count().intValue(); + this.model = ejb.findAll(((getPageIndex() - 1) * getRecords()), getRecords()); + + if (records > 0) { + pages = records <= 0 ? 1 : recordsTotal / records; + + if (recordsTotal % records > 0) { + pages++; + } + + if (pages == 0) { + pages = 1; + } + } else { + records = 1; + pages = 1; + } + } + + private boolean isNext() { + return this.pageIndex < pages; + } + + public void next() { + if (isNext()) { + this.pageIndex++; + } + + updateModel(); + } + + private boolean isPrev() { + return this.pageIndex > 1; + } + + public void prev() { + if (isPrev()) { + this.pageIndex--; + } + + updateModel(); + } + + public void setRecords(int records) { + this.records = records; + } + + public int getRecords() { + return records; + } + + public int getRecordsTotal() { + return recordsTotal; + } + + public void setPageIndex(int pageIndex) { + this.pageIndex = pageIndex; + } + + public int getPageIndex() { + return pageIndex; + } + + public int getPages() { + return pages; + } + + public int getFirst() { + return (pageIndex * records) - records; + } + + public List getModel() { + return model; + } +} \ No newline at end of file diff --git a/war/src/main/java/be/dabla/service/AbstractAsynchronousWebService.java b/war/src/main/java/be/dabla/service/AbstractAsynchronousWebService.java new file mode 100644 index 0000000..b7db5cf --- /dev/null +++ b/war/src/main/java/be/dabla/service/AbstractAsynchronousWebService.java @@ -0,0 +1,46 @@ +package be.dabla.service; + +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.ws.WebServiceContext; + +import be.dabla.AbstractInitialContextProvider; +import be.dabla.service.handler.Address; +import be.dabla.service.util.MessageContextAddressingHelper; + +public abstract class AbstractAsynchronousWebService extends AbstractInitialContextProvider { + static final Logger logger = Logger.getLogger(AbstractAsynchronousWebService.class.getName()); + + protected abstract WebServiceContext getWebServiceContext(); + + protected Address getAddress(final T content) { + logger.log(Level.FINE, "content: ", content); + + if (content != null) { + try { + final MessageContextAddressingHelper helper = new MessageContextAddressingHelper(getWebServiceContext().getMessageContext()); + final String messageId = helper.getMessageId(); + final String replyTo = helper.getReplyTo(); + final String to = helper.getTo(); + final Map parameters = helper.getReferenceParameters(); + + logger.log(Level.FINE, "messageId: {0}", messageId); + logger.log(Level.FINE, "replyTo: {0}", replyTo); + logger.log(Level.FINE, "to: {0}", to); + logger.log(Level.FINE, "parameters: {0}", parameters); + + if ((messageId != null) && (replyTo != null) && (to != null)) { + + return new Address(content, messageId, to, replyTo, parameters); + } + } + catch(Exception e) { + throw new RuntimeException(e); + } + } + + return null; + } +} \ No newline at end of file diff --git a/war/src/main/java/be/dabla/service/impl/MessageServiceImpl.java b/war/src/main/java/be/dabla/service/impl/MessageServiceImpl.java new file mode 100644 index 0000000..e7de587 --- /dev/null +++ b/war/src/main/java/be/dabla/service/impl/MessageServiceImpl.java @@ -0,0 +1,54 @@ +package be.dabla.service.impl; + +import java.util.logging.Logger; + +import javax.annotation.Resource; +import javax.ejb.Stateless; +import javax.jws.WebService; +import javax.naming.NamingException; +import javax.xml.ws.WebServiceContext; +import javax.xml.ws.soap.Addressing; + +import be.dabla.domain.MessageMDBSender; +import be.dabla.domain.MessageMDBSenderRemote; +import be.dabla.model.Message; +import be.dabla.service.AbstractAsynchronousWebService; +import be.dabla.service.MessageService; + +@Stateless +@Addressing +@WebService( + serviceName = "MessageService", + portName = "MessageServicePort", + targetNamespace = "urn:service.dabla.be", + endpointInterface = "be.dabla.service.MessageService") +// http://biemond.blogspot.com/2011/02/building-asynchronous-web-service-with.html +public class MessageServiceImpl extends AbstractAsynchronousWebService implements MessageService { + private static final Logger logger = Logger.getLogger(MessageServiceImpl.class.getName()); + + @Resource + WebServiceContext context; + private final MessageMDBSenderRemote ejb; + + public MessageServiceImpl() throws NamingException { + ejb = (MessageMDBSenderRemote)initialContext.lookup(MessageMDBSender.class.getSimpleName()); + } + + @Override + public void create(final Message payload) { + try { + ejb.sendMessage(getAddress(payload)); + } + catch(Exception e) { + logger.severe(e.getMessage()); + } + } + + protected WebServiceContext getWebServiceContext() { + return context; + } + + @Override + public void callbackMessage(final Message payload) { + } +} \ No newline at end of file diff --git a/war/src/main/java/be/dabla/service/util/MessageContextAddressingHelper.java b/war/src/main/java/be/dabla/service/util/MessageContextAddressingHelper.java new file mode 100644 index 0000000..cebbb9f --- /dev/null +++ b/war/src/main/java/be/dabla/service/util/MessageContextAddressingHelper.java @@ -0,0 +1,146 @@ +package be.dabla.service.util; + +import java.io.IOException; +import java.io.StringReader; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.ws.handler.MessageContext; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +public class MessageContextAddressingHelper { + static final Logger logger = Logger.getLogger(MessageContextAddressingHelper.class.getName()); + + final DocumentBuilder builder; + final String messageId; + final String to; + final String replyTo; + final Map parameters; + + public MessageContextAddressingHelper(final MessageContext messageContext) throws ParserConfigurationException, SAXException, IOException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { + this.builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + + logger.log(Level.FINE, "messageContext: {0}", messageContext); + + if (messageContext.containsKey("com.sun.xml.ws.api.addressing.messageId")) { + messageId = (String)messageContext.get("com.sun.xml.ws.api.addressing.messageId"); + to = getAddress(messageContext.get("com.sun.xml.ws.api.addressing.to")); + replyTo = getAddress(messageContext.get("com.sun.xml.ws.addressing.WsaPropertyBag.ReplyToFromRequest")); + parameters = getReferenceParameters(messageContext.get("com.sun.xml.ws.addressing.WsaPropertyBag.ReplyToFromRequest")); + } + else { + if (messageContext.containsKey("javax.xml.ws.addressing.context.inbound")) { + messageId = getAttributedURITypeValue(messageContext.get("javax.xml.ws.addressing.context.inbound"), "getMessageID"); + to = getAttributedURITypeValue(messageContext.get("javax.xml.ws.addressing.context.inbound"), "getTo"); + replyTo = getEndpointReferenceTypeValue(messageContext.get("javax.xml.ws.addressing.context.inbound"), "getReplyTo"); + } + else { + messageId = null; + to = null; + replyTo = null; + } + + parameters = null; + } + } + + public String getMessageId() { + return messageId; + } + + public String getTo() { + return to; + } + + public String getReplyTo() { + return replyTo; + } + + public Map getReferenceParameters() { + return parameters; + } + + protected String getAddress(final Object value) throws SAXException, IOException { + final Node node = findNode(value, "Address"); + + if (node != null) { + return node.getTextContent(); + } + + return null; + } + + + protected Map getReferenceParameters(final Object value) throws SAXException, IOException { + final Node node = findNode(value, "ReferenceParameters"); + + if (node != null) { + final Map parameters = new HashMap(); + final NodeList children = node.getChildNodes(); + + for (int i = 0; i < children.getLength(); i++) { + final int index = children.item(i).getNodeName().indexOf(':'); + + parameters.put((index > -1 ? children.item(i).getNodeName().substring(index + 1) : children.item(i).getNodeName()), children.item(i).getTextContent()); + } + + return parameters; + } + + return null; + } + + protected Node findNode(final Object value, final String name) throws SAXException, IOException { + if (value != null) { + final NodeList list = toDocument(value.toString()).getChildNodes(); + + for (int i = 0; i < list.getLength(); i++) { + final NodeList children = list.item(i).getChildNodes(); + + for (int j = 0; j < children.getLength(); j++) { + if (children.item(j).getNodeName().endsWith(name)) { + return children.item(j); + } + } + } + } + + return null; + } + + + protected String getEndpointReferenceTypeValue(final Object instance, final String name) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + final Object object = instance.getClass().getDeclaredMethod(name, null).invoke(instance, null); + + if (object != null) { + return getAttributedURITypeValue(object, "getAddress"); + } + + return null; + } + + protected String getAttributedURITypeValue(final Object instance, final String name) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + final Object object = instance.getClass().getDeclaredMethod(name, null).invoke(instance, null); + + if (object != null) { + return (String)object.getClass().getDeclaredMethod("getValue", null).invoke(object, null); + } + + return null; + } + + protected Document toDocument(final String value) throws SAXException, IOException { + return builder.parse(new InputSource(new StringReader(value))); + } +} \ No newline at end of file diff --git a/war/src/main/resources/env-entry.properties b/war/src/main/resources/env-entry.properties new file mode 100644 index 0000000..c9c0fe4 --- /dev/null +++ b/war/src/main/resources/env-entry.properties @@ -0,0 +1,3 @@ +java.naming.factory.initial=org.apache.openejb.client.LocalInitialContextFactory +openejb.embedded.remotable=true +openejb.vendor.config=NONE \ No newline at end of file diff --git a/war/src/main/resources/web.xml b/war/src/main/resources/web.xml new file mode 100644 index 0000000..67690e6 --- /dev/null +++ b/war/src/main/resources/web.xml @@ -0,0 +1,34 @@ + + + + + javax.faces.PROJECT_STAGE + ${stage} + + + + + index.xhtml + + + ${servlet} + + + + Faces Servlet + javax.faces.webapp.FacesServlet + 2 + + + ${servlet-mapping} + + + + Faces Servlet + *.xhtml + + + ${persistence} + \ No newline at end of file diff --git a/war/src/main/resources/wsdl/MessageService.wsdl b/war/src/main/resources/wsdl/MessageService.wsdl new file mode 100644 index 0000000..df4986d --- /dev/null +++ b/war/src/main/resources/wsdl/MessageService.wsdl @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/war/src/main/resources/wsdl/MessageService_schema1.xsd b/war/src/main/resources/wsdl/MessageService_schema1.xsd new file mode 100644 index 0000000..4ae2917 --- /dev/null +++ b/war/src/main/resources/wsdl/MessageService_schema1.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/war/src/main/resources/wsdl/MessageService_schema2.xsd b/war/src/main/resources/wsdl/MessageService_schema2.xsd new file mode 100644 index 0000000..967db77 --- /dev/null +++ b/war/src/main/resources/wsdl/MessageService_schema2.xsd @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/war/src/main/webapp/WEB-INF/faces-config.xml b/war/src/main/webapp/WEB-INF/faces-config.xml new file mode 100644 index 0000000..2a3b2b4 --- /dev/null +++ b/war/src/main/webapp/WEB-INF/faces-config.xml @@ -0,0 +1,17 @@ + + + + + en + + + + messageController + be.dabla.model.MessageController + request + + \ No newline at end of file diff --git a/war/src/main/webapp/index.xhtml b/war/src/main/webapp/index.xhtml new file mode 100644 index 0000000..0c113a7 --- /dev/null +++ b/war/src/main/webapp/index.xhtml @@ -0,0 +1,40 @@ + + + Messages + + +

Messages

+
+ + + + + + + + + + + + + + + + +
IdDescriptionDate
${item.id}${item.description} + + + +
+ + ${messageController.paginator.pageIndex} / ${messageController.paginator.pages} + + + + + \ No newline at end of file diff --git a/war/src/main/webapp/resources/css/reset.css b/war/src/main/webapp/resources/css/reset.css new file mode 100644 index 0000000..af94440 --- /dev/null +++ b/war/src/main/webapp/resources/css/reset.css @@ -0,0 +1,48 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} \ No newline at end of file diff --git a/war/src/main/webapp/templates/layout.xhtml b/war/src/main/webapp/templates/layout.xhtml new file mode 100644 index 0000000..1cf5009 --- /dev/null +++ b/war/src/main/webapp/templates/layout.xhtml @@ -0,0 +1,19 @@ + + + + + + + <ui:insert name="title" /> + + + + + + + \ No newline at end of file diff --git a/war/src/test/java/be/dabla/model/RequestControllerTest.java b/war/src/test/java/be/dabla/model/RequestControllerTest.java new file mode 100644 index 0000000..a86491c --- /dev/null +++ b/war/src/test/java/be/dabla/model/RequestControllerTest.java @@ -0,0 +1,23 @@ +package be.dabla.model; + +import static org.junit.Assert.assertNotNull; + +import javax.naming.NamingException; + +import org.apache.openejb.OpenEJBTestCase; +import org.apache.openejb.api.LocalClient; +import org.junit.Test; + +import be.dabla.model.Message; + +@LocalClient +public class RequestControllerTest extends OpenEJBTestCase { + @Test + public void testPaginator() throws NamingException { + final MessageController controller = new MessageController(); + final RepeatPaginator paginator = controller.getPaginator(); + assertNotNull(paginator); + paginator.prev(); + paginator.next(); + } +} \ No newline at end of file diff --git a/war/src/test/java/be/dabla/service/MessageServiceTest.java b/war/src/test/java/be/dabla/service/MessageServiceTest.java new file mode 100644 index 0000000..d3873a0 --- /dev/null +++ b/war/src/test/java/be/dabla/service/MessageServiceTest.java @@ -0,0 +1,29 @@ +package be.dabla.service; + +import javax.xml.ws.WebServiceRef; + +import org.apache.openejb.api.LocalClient; +import org.junit.Test; + +import be.dabla.model.Message; + +@LocalClient +public class MessageServiceTest extends WebServiceTestCase { + @WebServiceRef(wsdlLocation = "http://127.0.0.1:4204/MessageServiceImpl?wsdl") + private MessageService port; + + public MessageService getPort() { + return port; + } + + //http://svn.apache.org/repos/asf/openejb/tags/openejb-3.1.1/examples/simple-webservice/src/main/java/org/superbiz/calculator/CalculatorImpl.java + @Test + public void testCreate() throws Exception { + getPort().create(new Message("Hello David")); + } + + @Test + public void testCallbackMessage() { + getPort().callbackMessage(new Message("Hello David")); + } +} \ No newline at end of file diff --git a/war/src/test/java/be/dabla/service/WebServiceTestCase.java b/war/src/test/java/be/dabla/service/WebServiceTestCase.java new file mode 100644 index 0000000..6202904 --- /dev/null +++ b/war/src/test/java/be/dabla/service/WebServiceTestCase.java @@ -0,0 +1,63 @@ +package be.dabla.service; + +import static org.apache.cxf.ws.addressing.JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES; + +import javax.xml.ws.BindingProvider; + +import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor; +import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor; +import org.apache.cxf.endpoint.Client; +import org.apache.cxf.endpoint.Endpoint; +import org.apache.cxf.frontend.ClientProxy; +import org.apache.cxf.jaxws.support.JaxWsEndpointImpl; +import org.apache.cxf.ws.addressing.AddressingProperties; +import org.apache.cxf.ws.addressing.AddressingPropertiesImpl; +import org.apache.cxf.ws.addressing.WSAddressingFeature; +import org.apache.openejb.OpenEJBTestCase; +import org.junit.After; +import org.junit.Before; + + +public abstract class WebServiceTestCase extends OpenEJBTestCase { + public abstract T getPort(); + + /*@Before + public void setUp() throws Exception { + super.setUp(); + + final Client client = ClientProxy.getClient(getPort()); + final Endpoint endpoint = client.getEndpoint(); + endpoint.getInInterceptors().add(new SAAJInInterceptor()); + endpoint.getOutInterceptors().add(new SAAJOutInterceptor()); + + enableWSAddressing(); + } + + @After + public void tearDown() throws Exception { + super.tearDown(); + + final Endpoint endpoint = ClientProxy.getClient(getPort()).getEndpoint(); + endpoint.getInInterceptors().clear(); + endpoint.getOutInterceptors().clear(); + + disableWSAddressing(); + } + + protected void enableWSAddressing() { + final Client client = ClientProxy.getClient(getPort()); + final Endpoint endpoint = client.getEndpoint(); + final WSAddressingFeature addressingFeature = new WSAddressingFeature(); + addressingFeature.setAddressingRequired(true); + final AddressingProperties maps = new AddressingPropertiesImpl(); + maps.setReplyTo(endpoint.getEndpointInfo().getTarget()); + ((BindingProvider)getPort()).getRequestContext().put(CLIENT_ADDRESSING_PROPERTIES, maps); + ((JaxWsEndpointImpl)client.getEndpoint()).getFeatures().add(addressingFeature); + } + + protected void disableWSAddressing() { + final Client client = ClientProxy.getClient(getPort()); + ((BindingProvider)getPort()).getRequestContext().clear(); + ((JaxWsEndpointImpl)client.getEndpoint()).getFeatures().clear(); + }*/ +} \ No newline at end of file diff --git a/war/src/test/java/be/dabla/service/util/MessageContextAddressingHelperTest.java b/war/src/test/java/be/dabla/service/util/MessageContextAddressingHelperTest.java new file mode 100644 index 0000000..18e7a05 --- /dev/null +++ b/war/src/test/java/be/dabla/service/util/MessageContextAddressingHelperTest.java @@ -0,0 +1,19 @@ +package be.dabla.service.util; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import be.dabla.service.MockMessageContext; +import be.dabla.service.util.MessageContextAddressingHelper; + +public class MessageContextAddressingHelperTest { + @Test + public void testHelper() throws Exception { + final MessageContextAddressingHelper helper = new MessageContextAddressingHelper(new MockMessageContext()); + + assertNotNull(helper.getMessageId()); + assertNotNull(helper.getReplyTo()); + assertNotNull(helper.getTo()); + } +} \ No newline at end of file diff --git a/war/src/test/java/be/dabla/servlet/CXFServlet.java b/war/src/test/java/be/dabla/servlet/CXFServlet.java new file mode 100644 index 0000000..a8e2998 --- /dev/null +++ b/war/src/test/java/be/dabla/servlet/CXFServlet.java @@ -0,0 +1,114 @@ +package be.dabla.servlet; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.jws.WebService; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.xml.ws.Endpoint; + +import org.apache.cxf.BusFactory; +import org.apache.cxf.frontend.ServerFactoryBean; +import org.apache.cxf.transport.servlet.CXFNonSpringServlet; + +public class CXFServlet extends CXFNonSpringServlet { + private static final Logger logger = Logger.getLogger(CXFServlet.class.getName()); + + private String packageName; + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public void init() + throws ServletException + { + setPackageName(getServletConfig().getInitParameter("package")); + } + + @Override + public void loadBus(final ServletConfig servletConfig) throws ServletException { + super.loadBus(servletConfig); + + BusFactory.setDefaultBus(bus); + + try { + logger.log(Level.FINE, "packageName: {0}", getPackageName()); + + for (final Class implementation : getClasses(getPackageName())) { + final WebService annotation = (WebService)implementation.getAnnotation(WebService.class); + + logger.log(Level.FINE, "annotation: {0}", annotation); + + // only accept classes which are annotated with the WebService annotation + if (annotation != null) { + logger.log(Level.INFO, "Publishing endpoint ''{0}'' for class ''{1}''.", new Object[]{annotation.serviceName(),implementation.getName()}); + + Endpoint.publish("/" + annotation.serviceName(), implementation.newInstance()); + } + } + } catch(Exception e) { + throw new ServletException(e); + } + } + + /** + * Scans all classes accessible from the context class loader which belong to the given package and subpackages. + * + * @param packageName The base package + * @return The classes + * @throws ClassNotFoundException + * @throws IOException + * @throws URISyntaxException + */ + private static Class[] getClasses(final String packageName) + throws ClassNotFoundException, IOException, URISyntaxException { + final Enumeration resources = Thread.currentThread().getContextClassLoader().getResources(packageName.replace('.', '/')); + final List dirs = new ArrayList(); + while (resources.hasMoreElements()) { + dirs.add(new File(resources.nextElement().toURI())); + } + final ArrayList classes = new ArrayList(); + for (final File directory : dirs) { + classes.addAll(findClasses(directory, packageName)); + } + return classes.toArray(new Class[classes.size()]); + } + + /** + * Recursive method used to find all classes in a given directory and subdirs. + * + * @param directory The base directory + * @param packageName The package name for classes found inside the base directory + * @return The classes + * @throws ClassNotFoundException + */ + private static List findClasses(File directory, String packageName) throws ClassNotFoundException { + final List classes = new ArrayList(); + if (!directory.exists()) { + return classes; + } + final File[] files = directory.listFiles(); + for (File file : files) { + if (file.isDirectory()) { + assert !file.getName().contains("."); + classes.addAll(findClasses(file, packageName + '.' + file.getName())); + } else if (file.getName().endsWith(".class")) { + classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6))); + } + } + return classes; + } +} \ No newline at end of file diff --git a/war/src/test/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java b/war/src/test/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java new file mode 100644 index 0000000..684e257 --- /dev/null +++ b/war/src/test/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java @@ -0,0 +1,654 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cxf.jaxws.support; + +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.jws.WebMethod; +import javax.wsdl.Operation; +import javax.xml.bind.annotation.XmlNsForm; +import javax.xml.bind.annotation.XmlSchema; +import javax.xml.bind.annotation.XmlSeeAlso; +import javax.xml.namespace.QName; +import javax.xml.ws.Action; +import javax.xml.ws.AsyncHandler; +import javax.xml.ws.BindingType; +import javax.xml.ws.FaultAction; +import javax.xml.ws.Provider; +import javax.xml.ws.Service; +import javax.xml.ws.WebFault; +import javax.xml.ws.WebServiceFeature; +import javax.xml.ws.soap.Addressing; +import javax.xml.ws.soap.AddressingFeature; +import javax.xml.ws.soap.MTOM; +import javax.xml.ws.soap.MTOMFeature; +import javax.xml.ws.soap.SOAPBinding; + +import org.apache.cxf.common.classloader.ClassLoaderUtils; +import org.apache.cxf.common.i18n.Message; +import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.common.util.PackageUtils; +import org.apache.cxf.common.util.StringUtils; +import org.apache.cxf.common.util.XMLSchemaQNames; +import org.apache.cxf.databinding.DataBinding; +import org.apache.cxf.databinding.source.SourceDataBinding; +import org.apache.cxf.endpoint.Endpoint; +import org.apache.cxf.endpoint.EndpointException; +import org.apache.cxf.helpers.CastUtils; +import org.apache.cxf.jaxws.JAXWSMethodDispatcher; +import org.apache.cxf.jaxws.JAXWSProviderMethodDispatcher; +import org.apache.cxf.jaxws.WrapperClassGenerator; +import org.apache.cxf.jaxws.interceptors.WebFaultOutInterceptor; +import org.apache.cxf.service.factory.AbstractServiceConfiguration; +import org.apache.cxf.service.factory.ReflectionServiceFactoryBean; +import org.apache.cxf.service.factory.ServiceConstructionException; +import org.apache.cxf.service.model.BindingInfo; +import org.apache.cxf.service.model.BindingOperationInfo; +import org.apache.cxf.service.model.EndpointInfo; +import org.apache.cxf.service.model.FaultInfo; +import org.apache.cxf.service.model.InterfaceInfo; +import org.apache.cxf.service.model.MessageInfo; +import org.apache.cxf.service.model.MessagePartInfo; +import org.apache.cxf.service.model.OperationInfo; +import org.apache.cxf.service.model.ServiceInfo; +import org.apache.cxf.ws.addressing.JAXWSAConstants; +import org.apache.cxf.wsdl11.WSDLServiceBuilder; + +/** + * Constructs a service model from JAX-WS service endpoint classes. Works + * with both @@WebServiceProvider and @@WebService annotated classes. + * + * @see org.apache.cxf.jaxws.JaxWsServerFactoryBean + */ +// http://community.jboss.org/message/608047 +public class JaxWsServiceFactoryBean extends ReflectionServiceFactoryBean { + // used to tag property on service. + public static final String WS_FEATURES = "JAXWS-WS-FEATURES"; + private static final Logger LOG = LogUtils.getLogger(JaxWsServiceFactoryBean.class); + + private AbstractServiceConfiguration jaxWsConfiguration; + + private JaxWsImplementorInfo implInfo; + + private List setWsFeatures; + private List wsFeatures; + + private boolean wrapperBeanGenerated; + private Set> wrapperClasses; + + + public JaxWsServiceFactoryBean() { + getIgnoredClasses().add(Service.class.getName()); + + //the JAXWS-RI doesn't qualify the schemas for the wrapper types + //and thus won't work if we do. + setQualifyWrapperSchema(false); + initSchemaLocations(); + } + + public JaxWsServiceFactoryBean(JaxWsImplementorInfo implInfo) { + this(); + this.implInfo = implInfo; + initConfiguration(implInfo); + this.serviceClass = implInfo.getEndpointClass(); + this.serviceType = implInfo.getSEIType(); + loadWSFeatureAnnotation(implInfo.getSEIClass(), implInfo.getImplementorClass()); + } + + @Override + public void reset() { + super.reset(); + wrapperBeanGenerated = false; + wrapperClasses = null; + } + + private void initSchemaLocations() { + this.schemaLocationMapping.put(JAXWSAConstants.NS_WSA, + JAXWSAConstants.WSA_XSD); + } + + private void loadWSFeatureAnnotation(Class serviceClass, Class implementorClass) { + List features = new ArrayList(); + MTOM mtom = implInfo.getImplementorClass().getAnnotation(MTOM.class); + if (mtom == null && serviceClass != null) { + mtom = serviceClass.getAnnotation(MTOM.class); + } + if (mtom != null) { + features.add(new MTOMFeature(mtom.enabled(), mtom.threshold())); + } else { + //deprecated way to set mtom + BindingType bt = implInfo.getImplementorClass().getAnnotation(BindingType.class); + if (bt != null + && (SOAPBinding.SOAP11HTTP_MTOM_BINDING.equals(bt.value()) + || SOAPBinding.SOAP12HTTP_MTOM_BINDING.equals(bt.value()))) { + features.add(new MTOMFeature(true)); + } + } + + + Addressing addressing = null; + if (implementorClass != null) { + addressing = implementorClass.getAnnotation(Addressing.class); + } + + if (addressing == null && serviceClass != null) { + addressing = serviceClass.getAnnotation(Addressing.class); + } + + if (addressing != null) { + features.add(new AddressingFeature(addressing.enabled(), addressing.required())); + } + + if (features.size() > 0) { + wsFeatures = features; + if (setWsFeatures != null) { + wsFeatures.addAll(setWsFeatures); + } + } else { + wsFeatures = setWsFeatures; + } + } + + @Override + public org.apache.cxf.service.Service create() { + org.apache.cxf.service.Service s = super.create(); + + s.put(ENDPOINT_CLASS, implInfo.getEndpointClass()); + + return s; + } + + + @Override + public void setServiceClass(Class serviceClass) { + if (serviceClass == null) { + Message message = new Message("SERVICECLASS_MUST_BE_SET", LOG); + throw new ServiceConstructionException(message); + } + setJaxWsImplementorInfo(new JaxWsImplementorInfo(serviceClass)); + super.setServiceClass(getJaxWsImplementorInfo().getEndpointClass()); + super.setServiceType(getJaxWsImplementorInfo().getSEIType()); + } + @Override + protected void checkServiceClassAnnotations(Class sc) { + //no need to check + } + + @Override + protected void initializeFaultInterceptors() { + getService().getOutFaultInterceptors().add(new WebFaultOutInterceptor()); + } + + @Override + public Endpoint createEndpoint(EndpointInfo ei) throws EndpointException { + return new JaxWsEndpointImpl(getBus(), getService(), ei, implInfo, wsFeatures, + this.getFeatures(), this.isFromWsdl()); + } + + @Override + protected void initializeWSDLOperation(InterfaceInfo intf, OperationInfo o, Method method) { + method = ((JaxWsServiceConfiguration)jaxWsConfiguration).getDeclaredMethod(method); + o.setProperty(Method.class.getName(), method); + o.setProperty(METHOD, method); + initializeWrapping(o, method); + + // rpc out-message-part-info class mapping + Operation op = (Operation)o.getProperty(WSDLServiceBuilder.WSDL_OPERATION); + + initializeClassInfo(o, method, op == null ? null + : CastUtils.cast(op.getParameterOrdering(), String.class)); + + bindOperation(o, method); + } + + protected void bindOperation(OperationInfo op, Method method) { + + try { + // Find the Async method which returns a Response + Method responseMethod = method.getDeclaringClass().getDeclaredMethod(method.getName() + "Async", + method.getParameterTypes()); + + // Find the Async method whic has a Future & AsyncResultHandler + List> asyncHandlerParams = Arrays.asList(method.getParameterTypes()); + //copy it to may it non-readonly + asyncHandlerParams = new ArrayList>(asyncHandlerParams); + asyncHandlerParams.add(AsyncHandler.class); + Method futureMethod = method.getDeclaringClass() + .getDeclaredMethod(method.getName() + "Async", + asyncHandlerParams.toArray(new Class[asyncHandlerParams.size()])); + + getMethodDispatcher().bind(op, method, responseMethod, futureMethod); + + } catch (SecurityException e) { + throw new ServiceConstructionException(e); + } catch (NoSuchMethodException e) { + getMethodDispatcher().bind(op, method); + } + } + + @Override + protected void initializeWSDLOperations() { + if (implInfo.isWebServiceProvider()) { + initializeWSDLOperationsForProvider(); + } else { + super.initializeWSDLOperations(); + } + } + + protected void initializeWSDLOperationsForProvider() { + Class c = getProviderParameterType(getServiceClass()); + if (c == null) { + throw new ServiceConstructionException(new Message("INVALID_PROVIDER_EXC", LOG)); + } + + if (getEndpointInfo() == null + && isFromWsdl()) { + //most likely, they specified a WSDL, but for some reason + //did not give a valid ServiceName/PortName. For provider, + //we'll allow this since everything is bound directly to + //the invoke method, however, this CAN cause other problems + //such as addresses in the wsdl not getting updated and such + //so we'll WARN about it..... + List enames = new ArrayList(); + for (ServiceInfo si : getService().getServiceInfos()) { + for (EndpointInfo ep : si.getEndpoints()) { + enames.add(ep.getName()); + } + } + LOG.log(Level.WARNING, "COULD_NOT_FIND_ENDPOINT", + new Object[] {getEndpointName(), enames}); + } + + try { + Method invoke = getServiceClass().getMethod("invoke", c); + QName catchAll = new QName("http://cxf.apache.org/jaxws/provider", "invoke"); + + // Bind every operation to the invoke method. + for (ServiceInfo si : getService().getServiceInfos()) { + si.setProperty("soap.force.doclit.bare", Boolean.TRUE); + for (BindingInfo bind : si.getBindings()) { + for (BindingOperationInfo bop : bind.getOperations()) { + OperationInfo o = bop.getOperationInfo(); + if (o.getInput() != null) { + if (o.getInput().getMessageParts().isEmpty()) { + MessagePartInfo inf = o.getInput().addMessagePart(o.getName()); + inf.setConcreteName(o.getName()); + bop.getInput().setMessageParts(o.getInput().getMessageParts()); + } + for (MessagePartInfo inf : o.getInput().getMessageParts()) { + inf.setTypeClass(c); + break; + } + } + if (o.getOutput() != null) { + if (o.getOutput().getMessageParts().isEmpty()) { + MessagePartInfo inf = o.getOutput().addMessagePart(o.getName()); + inf.setConcreteName(new QName(o.getName().getNamespaceURI(), + o.getName().getLocalPart() + "Response")); + bop.getOutput().setMessageParts(o.getOutput().getMessageParts()); + } + for (MessagePartInfo inf : o.getOutput().getMessageParts()) { + inf.setTypeClass(c); + break; + } + } + getMethodDispatcher().bind(o, invoke); + } + BindingOperationInfo bop = bind.getOperation(catchAll); + if (bop == null) { + OperationInfo op = bind.getInterface().getOperation(catchAll); + if (op == null) { + op = bind.getInterface().addOperation(catchAll); + String name = catchAll.getLocalPart(); + MessageInfo mInfo = op.createMessage(new QName(catchAll.getNamespaceURI(), + name + "Request"), + MessageInfo.Type.INPUT); + op.setInput(catchAll.getLocalPart() + "Request", mInfo); + MessagePartInfo mpi = mInfo.addMessagePart("parameters"); + mpi.setElement(true); + mpi.setTypeClass(c); + mpi.setTypeQName(XMLSchemaQNames.XSD_ANY); + + mInfo = op.createMessage(new QName(catchAll.getNamespaceURI(), + name + "Response"), + MessageInfo.Type.OUTPUT); + op.setOutput(name + "Response", mInfo); + mpi = mInfo.addMessagePart("parameters"); + mpi.setElement(true); + mpi.setTypeClass(c); + mpi.setTypeQName(XMLSchemaQNames.XSD_ANY); + + BindingOperationInfo bo = new BindingOperationInfo(bind, op); + op.setProperty("operation.is.synthetic", Boolean.TRUE); + bo.setProperty("operation.is.synthetic", Boolean.TRUE); + bind.addOperation(bo); + } + } + } + } + } catch (SecurityException e) { + throw new ServiceConstructionException(e); + } catch (NoSuchMethodException e) { + throw new ServiceConstructionException(e); + } + + + } + + protected Class getProviderParameterType(Class cls) { + if (cls == null) { + return null; + } + Type[] genericInterfaces = cls.getGenericInterfaces(); + for (Type type : genericInterfaces) { + if (type instanceof ParameterizedType) { + Class rawCls = (Class)((ParameterizedType)type).getRawType(); + if (Provider.class == rawCls) { + return (Class)((ParameterizedType)type).getActualTypeArguments()[0]; + } + } else if (type instanceof Class && Provider.class.isAssignableFrom((Class)type)) { + return getProviderParameterType((Class)type); + } + } + return getProviderParameterType(cls.getSuperclass()); + } + + void initializeWrapping(OperationInfo o, Method selected) { + Class responseWrapper = getResponseWrapper(selected); + if ((responseWrapper != null) && (o.getOutput() != null)) { + o.getOutput().getMessageParts().get(0).setTypeClass(responseWrapper); + } + if ((getResponseWrapperClassName(selected) != null) && (o.getOutput() != null)) { + o.getOutput().getMessageParts().get(0).setProperty("RESPONSE.WRAPPER.CLASSNAME", + getResponseWrapperClassName(selected)); + } + Class requestWrapper = getRequestWrapper(selected); + if (requestWrapper != null) { + o.getInput().getMessageParts().get(0).setTypeClass(requestWrapper); + } + if (getRequestWrapperClassName(selected) != null) { + o.getInput().getMessageParts().get(0).setProperty("REQUEST.WRAPPER.CLASSNAME", + getRequestWrapperClassName(selected)); + } + } + + + @Override + protected Class getBeanClass(Class exClass) { + try { + if (java.rmi.ServerException.class.isAssignableFrom(exClass) + || java.rmi.RemoteException.class.isAssignableFrom(exClass) + || "javax.xml.ws".equals(PackageUtils.getPackageName(exClass))) { + return null; + } + + Method getFaultInfo = exClass.getMethod("getFaultInfo", new Class[0]); + + return getFaultInfo.getReturnType(); + } catch (SecurityException e) { + throw new ServiceConstructionException(e); + } catch (NoSuchMethodException e) { + //ignore for now + } + WebFault fault = exClass.getAnnotation(WebFault.class); + if (fault != null && !StringUtils.isEmpty(fault.faultBean())) { + try { + return ClassLoaderUtils.loadClass(fault.faultBean(), + exClass); + } catch (ClassNotFoundException e1) { + //ignore + } + } + + return super.getBeanClass(exClass); + } + + public void setJaxWsConfiguration(JaxWsServiceConfiguration jaxWsConfiguration) { + this.jaxWsConfiguration = jaxWsConfiguration; + } + + public JaxWsImplementorInfo getJaxWsImplementorInfo() { + return implInfo; + } + + public void setJaxWsImplementorInfo(JaxWsImplementorInfo jaxWsImplementorInfo) { + this.implInfo = jaxWsImplementorInfo; + + initConfiguration(jaxWsImplementorInfo); + } + + protected final void initConfiguration(JaxWsImplementorInfo ii) { + if (ii.isWebServiceProvider()) { + jaxWsConfiguration = new WebServiceProviderConfiguration(); + jaxWsConfiguration.setServiceFactory(this); + getServiceConfigurations().add(0, jaxWsConfiguration); + setWrapped(false); + setDataBinding(new SourceDataBinding()); + setMethodDispatcher(new JAXWSProviderMethodDispatcher(implInfo)); + } else { + jaxWsConfiguration = new JaxWsServiceConfiguration(); + jaxWsConfiguration.setServiceFactory(this); + getServiceConfigurations().add(0, jaxWsConfiguration); + + Class seiClass = ii.getEndpointClass(); + if (seiClass != null && seiClass.getPackage() != null) { + XmlSchema schema = seiClass.getPackage().getAnnotation(XmlSchema.class); + if (schema != null && XmlNsForm.QUALIFIED.equals(schema.elementFormDefault())) { + setQualifyWrapperSchema(true); + } + } + setMethodDispatcher(new JAXWSMethodDispatcher(implInfo)); + } + loadWSFeatureAnnotation(ii.getSEIClass(), ii.getImplementorClass()); + } + + public List getWsFeatures() { + return setWsFeatures; + } + + public void setWsFeatures(List swsFeatures) { + this.setWsFeatures = swsFeatures; + if (wsFeatures == null) { + wsFeatures = setWsFeatures; + } + } + + private FaultInfo getFaultInfo(final OperationInfo operation, final Class expClass) { + for (FaultInfo fault : operation.getFaults()) { + if (fault.getProperty(Class.class.getName()) == expClass + || fault.getProperty(Class.class.getName()) == expClass) { + return fault; + } + } + return null; + } + private void buildWSAActions(OperationInfo operation, Method method) { + //nothing + if (method == null) { + return; + } + + Action action = method.getAnnotation(Action.class); + Addressing addressing = method.getDeclaringClass().getAnnotation(Addressing.class); + if (action == null && addressing == null) { + return; + } + WebMethod wm = method.getAnnotation(WebMethod.class); + String inputAction = ""; + if (action != null) { + inputAction = action.input(); + } + if (wm != null && StringUtils.isEmpty(inputAction)) { + inputAction = wm.action(); + } + if (StringUtils.isEmpty(inputAction)) { + inputAction = computeAction(operation, "Request"); + } + + if (action == null && addressing != null) { + operation.getInput().addExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME, + inputAction); + operation.getInput().addExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME, + inputAction); + + if (operation.getOutput() != null) { + operation.getOutput().addExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME, + computeAction(operation, "Response")); + operation.getOutput().addExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME, + computeAction(operation, "Response")); + } + + } else { + MessageInfo input = operation.getInput(); + input.addExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME, inputAction); + if (!StringUtils.isEmpty(action.input())) { + input.addExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME, inputAction); + } + + MessageInfo output = operation.getOutput(); + if (output != null && !StringUtils.isEmpty(action.output())) { + output.addExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME, action.output()); + output.addExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME, action.output()); + } else if (output != null) { + output.addExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME, computeAction(operation, + "Response")); + } + + FaultAction[] faultActions = action.fault(); + if (faultActions != null && faultActions.length > 0 && operation.getFaults() != null) { + for (FaultAction faultAction : faultActions) { + FaultInfo faultInfo = getFaultInfo(operation, faultAction.className()); + if (!StringUtils.isEmpty(faultAction.value())) { + faultInfo.addExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME, faultAction + .value()); + faultInfo.addExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME, faultAction + .value()); + } + if (operation.isUnwrappedCapable()) { + faultInfo = getFaultInfo(operation.getUnwrappedOperation(), faultAction.className()); + if (!StringUtils.isEmpty(faultAction.value())) { + faultInfo.addExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME, faultAction + .value()); + faultInfo.addExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME, faultAction + .value()); + } + } + } + } + } + for (FaultInfo fi : operation.getFaults()) { + if (fi.getExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME) == null) { + String f = "/Fault/" + fi.getName().getLocalPart(); + fi.addExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME, + computeAction(operation, f)); + if (operation.isUnwrappedCapable()) { + fi = operation.getUnwrappedOperation().getFault(fi.getName()); + fi.addExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME, + computeAction(operation, f)); + } + } + } + } + + private String computeAction(OperationInfo op, String postFix) { + StringBuilder s = new StringBuilder(op.getName().getNamespaceURI()); + if (s.charAt(s.length() - 1) != '/') { + s.append('/'); + } + s.append(op.getInterface().getName().getLocalPart()) + .append('/').append(op.getName().getLocalPart()).append(postFix); + return s.toString(); + } + + @Override + protected OperationInfo createOperation(ServiceInfo serviceInfo, InterfaceInfo intf, Method m) { + OperationInfo op = super.createOperation(serviceInfo, intf, m); + if (op.getUnwrappedOperation() != null) { + op = op.getUnwrappedOperation(); + } + buildWSAActions(op, m); + return op; + } + + @Override + protected Set> getExtraClass() { + Set> classes = new HashSet>(); + if (!wrapperBeanGenerated) { + wrapperClasses = generatedWrapperBeanClass(); + } + if (wrapperClasses != null) { + classes.addAll(wrapperClasses); + } + + XmlSeeAlso xmlSeeAlsoAnno = getServiceClass().getAnnotation(XmlSeeAlso.class); + + if (xmlSeeAlsoAnno != null && xmlSeeAlsoAnno.value() != null) { + for (int i = 0; i < xmlSeeAlsoAnno.value().length; i++) { + Class value = xmlSeeAlsoAnno.value()[i]; + if (value == null) { + LOG.log(Level.WARNING, "XMLSEEALSO_NULL_CLASS", + new Object[] {getServiceClass().getName(), i}); + } else { + classes.add(value); + } + + } + } + return classes; + } + + private Set> generatedWrapperBeanClass() { + DataBinding b = getDataBinding(); + if (b.getClass().getName().endsWith("JAXBDataBinding") + && schemaLocations == null) { + ServiceInfo serviceInfo = getService().getServiceInfos().get(0); + WrapperClassGenerator wrapperGen = new WrapperClassGenerator(this, + serviceInfo.getInterface(), + getQualifyWrapperSchema()); + return wrapperGen.generate(); + } + return Collections.emptySet(); + } + + @Override + protected void buildServiceFromClass() { + super.buildServiceFromClass(); + getService().put(WS_FEATURES, getWsFeatures()); + } + + protected void initializeParameter(MessagePartInfo part, Class rawClass, Type type) { + if (implInfo.isWebServiceProvider()) { + part.setTypeQName(XMLSchemaQNames.XSD_ANY); + part.setTypeClass(rawClass); + return; + } + super.initializeParameter(part, rawClass, type); + } +} diff --git a/war/src/test/resources/META-INF/ejb-jar.xml b/war/src/test/resources/META-INF/ejb-jar.xml new file mode 100644 index 0000000..433757b --- /dev/null +++ b/war/src/test/resources/META-INF/ejb-jar.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/war/src/test/resources/logging.properties b/war/src/test/resources/logging.properties new file mode 100644 index 0000000..c721942 --- /dev/null +++ b/war/src/test/resources/logging.properties @@ -0,0 +1,34 @@ +# Add handlers to the root logger. +# These are inherited by all other loggers. +handlers=java.util.logging.ConsoleHandler, java.util.logging.FileHandler + +# Configure the ConsoleHandler. +# ConsoleHandler uses java.util.logging.SimpleFormatter by default. +# Even though the root logger has the same level as this, +# the next line is still needed because we're configuring a handler, +# not a logger, and handlers don't inherit properties from the root logger. +java.util.logging.ConsoleHandler.level=FINE + +# Configure the FileHandler. +# FileHandler uses java.util.logging.XMLFormatter by default. +java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter +java.util.logging.FileHandler.level=FINEST + +# The following special tokens can be used in the pattern property +# which specifies the location and name of the log file. +# / - standard path separator +# %t - system temporary directory +# %h - value of the user.home system property +# %g - generation number for rotating logs +# %u - unique number to avoid conflicts +# FileHandler writes to %h/demo0.log by default. +java.util.logging.FileHandler.pattern=target/bc-syncro-test.log + +# Set the logging level of the root logger. +# Levels from lowest to highest are +# FINEST, FINER, FINE, CONFIG, INFO, WARNING and SEVERE. +# The default level for all loggers and handlers is INFO. +.level=INFO + +# Specify logging levels for specific namespaces. +be.infrabel.a087=FINEST \ No newline at end of file