Author: rmannibucau Date: Tue Oct 18 21:12:40 2016 New Revision: 1765511 URL: http://svn.apache.org/viewvc?rev=1765511&view=rev Log: adding some starting code for a mvn plugin
Added: openwebbeans/microwave/trunk/microwave-core/ openwebbeans/microwave/trunk/microwave-core/pom.xml openwebbeans/microwave/trunk/microwave-core/src/ openwebbeans/microwave/trunk/microwave-core/src/main/ openwebbeans/microwave/trunk/microwave-core/src/main/java/ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/Microwave.java openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/MicrowaveExplosion.java openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/BusInstance.java openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/CxfCdiAutoSetup.java openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/JAXRSCdiResourceExtensionWorkaround.java openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/openwebbeans/ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/openwebbeans/MicrowaveLoader.java openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/openwebbeans/OWBAutoSetup.java openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/tomcat/ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/tomcat/ProvidedLoader.java openwebbeans/microwave/trunk/microwave-core/src/main/resources/ openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/ openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/beans.xml openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/openwebbeans/ openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/openwebbeans/openwebbeans.properties openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/services/ openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension openwebbeans/microwave/trunk/microwave-core/src/test/ openwebbeans/microwave/trunk/microwave-core/src/test/java/ openwebbeans/microwave/trunk/microwave-core/src/test/java/org/ openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/ openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/ openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/MicrowaveTest.java openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/app/ openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/app/Endpoint.java openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/app/RsApp.java openwebbeans/microwave/trunk/microwave-maven-plugin/ openwebbeans/microwave/trunk/microwave-maven-plugin/pom.xml openwebbeans/microwave/trunk/microwave-maven-plugin/src/ openwebbeans/microwave/trunk/microwave-maven-plugin/src/main/ openwebbeans/microwave/trunk/microwave-maven-plugin/src/main/java/ openwebbeans/microwave/trunk/microwave-maven-plugin/src/main/java/org/ openwebbeans/microwave/trunk/microwave-maven-plugin/src/main/java/org/apache/ openwebbeans/microwave/trunk/microwave-maven-plugin/src/main/java/org/apache/microwave/ openwebbeans/microwave/trunk/microwave-maven-plugin/src/main/java/org/apache/microwave/maven/ openwebbeans/microwave/trunk/microwave-maven-plugin/src/main/java/org/apache/microwave/maven/MicrowaveRunMojo.java openwebbeans/microwave/trunk/microwave-maven-plugin/src/test/ openwebbeans/microwave/trunk/microwave-maven-plugin/src/test/java/ Removed: openwebbeans/microwave/trunk/src/ Modified: openwebbeans/microwave/trunk/TODO.txt openwebbeans/microwave/trunk/pom.xml Modified: openwebbeans/microwave/trunk/TODO.txt URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/TODO.txt?rev=1765511&r1=1765510&r2=1765511&view=diff ============================================================================== --- openwebbeans/microwave/trunk/TODO.txt (original) +++ openwebbeans/microwave/trunk/TODO.txt Tue Oct 18 21:12:40 2016 @@ -1,2 +1,2 @@ -- maven plugin +- maven plugin tests - main Added: openwebbeans/microwave/trunk/microwave-core/pom.xml URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/pom.xml?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-core/pom.xml (added) +++ openwebbeans/microwave/trunk/microwave-core/pom.xml Tue Oct 18 21:12:40 2016 @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://maven.apache.org/POM/4.0.0 + http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>microwave</artifactId> + <groupId>org.apache.microwave</groupId> + <version>0.0.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>microwave-core</artifactId> + <name>Microwave :: Core</name> + + <properties> + <openwebbeans.version>1.7.0</openwebbeans.version> + <tomcat.version>8.5.6</tomcat.version> + <cxf.version>3.1.7</cxf.version> + <johnzon.version>0.9.5</johnzon.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>1.16.10</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-annotation_1.2_spec</artifactId> + <version>1.0</version> + </dependency> + <dependency> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-jcdi_1.1_spec</artifactId> + <version>1.0</version> + </dependency> + <dependency> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-atinject_1.0_spec</artifactId> + <version>1.0</version> + </dependency> + <dependency> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-interceptor_1.2_spec</artifactId> + <version>1.0</version> + </dependency> + <dependency> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-json_1.0_spec</artifactId> + <version>1.0-alpha-1</version> + </dependency> + <dependency> + <groupId>org.apache.tomcat</groupId> + <artifactId>tomcat-servlet-api</artifactId> + <version>${tomcat.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + <version>3.4</version> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>2.4</version> + </dependency> + <dependency> + <groupId>org.apache.xbean</groupId> + <artifactId>xbean-reflect</artifactId> + <version>4.5</version> + </dependency> + <dependency> + <groupId>org.apache.openwebbeans</groupId> + <artifactId>openwebbeans-impl</artifactId> + <version>${openwebbeans.version}</version> + </dependency> + <dependency> + <groupId>org.apache.openwebbeans</groupId> + <artifactId>openwebbeans-web</artifactId> + <version>${openwebbeans.version}</version> + </dependency> + <dependency> + <groupId>org.apache.tomcat.embed</groupId> + <artifactId>tomcat-embed-core</artifactId> + <version>${tomcat.version}</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-frontend-jaxrs</artifactId> + <version>${cxf.version}</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-integration-cdi</artifactId> + <version>${cxf.version}</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-rs-client</artifactId> + <version>${cxf.version}</version> + </dependency> + <dependency> + <groupId>org.apache.johnzon</groupId> + <artifactId>johnzon-jaxrs</artifactId> + <version>${johnzon.version}</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>provided</scope> + </dependency> + </dependencies> +</project> \ No newline at end of file Added: openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/Microwave.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/Microwave.java?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/Microwave.java (added) +++ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/Microwave.java Tue Oct 18 21:12:40 2016 @@ -0,0 +1,1096 @@ +/* + * 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.microwave; + +import lombok.Data; +import lombok.Getter; +import lombok.experimental.Accessors; +import org.apache.catalina.Context; +import org.apache.catalina.Engine; +import org.apache.catalina.Globals; +import org.apache.catalina.Host; +import org.apache.catalina.Lifecycle; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.Manager; +import org.apache.catalina.Realm; +import org.apache.catalina.Server; +import org.apache.catalina.Service; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.session.ManagerBase; +import org.apache.catalina.session.StandardManager; +import org.apache.catalina.startup.Catalina; +import org.apache.catalina.startup.Tomcat; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.text.StrLookup; +import org.apache.commons.lang3.text.StrSubstitutor; +import org.apache.coyote.http2.Http2Protocol; +import org.apache.cxf.helpers.FileUtils; +import org.apache.microwave.cxf.CxfCdiAutoSetup; +import org.apache.microwave.openwebbeans.OWBAutoSetup; +import org.apache.microwave.tomcat.ProvidedLoader; +import org.apache.tomcat.util.descriptor.web.LoginConfig; +import org.apache.tomcat.util.descriptor.web.SecurityCollection; +import org.apache.tomcat.util.descriptor.web.SecurityConstraint; +import org.apache.xbean.finder.ResourceFinder; +import org.apache.xbean.recipe.ObjectRecipe; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Properties; +import java.util.TreeMap; +import java.util.function.Consumer; + +import static java.util.Collections.emptySet; +import static java.util.Optional.ofNullable; + +public class Microwave implements AutoCloseable { + @Getter + private final Builder configuration; + + protected InternalTomcat tomcat; + protected File base; + + // we can undeploy webapps with that later + private final Map<String, Context> contexts = new HashMap<>(); + + public Microwave(final Builder builder) { + this.configuration = builder; + } + + public Microwave deployClasspath() { + return deployClasspath(""); + } + + public Microwave deployClasspath(final String context) { + final File dir = new File(configuration.tempDir, "classpath/fake-" + context.replace("/", "")); + FileUtils.mkDir(dir); + return deployWebapp(context, dir, c -> c.setLoader(new ProvidedLoader(Thread.currentThread().getContextClassLoader()))); + } + + public Microwave deployWebapp(final File warOrDir) { + return deployWebapp("", warOrDir, null); + } + + public Microwave deployWebapp(final String context, final File warOrDir) { + return deployWebapp(context, warOrDir, null); + } + + public Microwave deployWebapp(final String context, final File warOrDir, final Consumer<Context> customizer) { + if (contexts.containsKey(context)) { + throw new IllegalArgumentException("Already deployed: '" + context + "'"); + } + + final Context ctx = new StandardContext(); + ctx.setPath(context); + ctx.setName(context); + try { + ctx.setDocBase(warOrDir.getCanonicalPath()); + } catch (final IOException e) { + ctx.setDocBase(warOrDir.getAbsolutePath()); + } + ctx.addLifecycleListener(new Tomcat.FixContextListener()); + ctx.addLifecycleListener(event -> { + switch (event.getType()) { + case Lifecycle.AFTER_START_EVENT: + ctx.getResources().setCachingAllowed(configuration.webResourceCached); + break; + case Lifecycle.BEFORE_START_EVENT: + if (configuration.loginConfig() != null) { + ctx.setLoginConfig(configuration.loginConfig().build()); + } + for (final SecurityConstaintBuilder sc : configuration.securityConstraints) { + ctx.addConstraint(sc.build()); + } + if (configuration.webXml != null) { + ctx.getServletContext().setAttribute(Globals.ALT_DD_ATTR, configuration.webXml); + } + break; + default: + } + + }); + + ctx.addServletContainerInitializer((c, ctx1) -> { + ctx.getServletContext().setAttribute("microwave.configuration", configuration); + try { + new OWBAutoSetup().onStartup(c, ctx1); + new CxfCdiAutoSetup().onStartup(c, ctx1); + } finally { + ctx.getServletContext().removeAttribute("microwave.configuration"); + } + }, emptySet()); + + ofNullable(customizer).ifPresent(c -> c.accept(ctx)); + + tomcat.getHost().addChild(ctx); + contexts.put(context, ctx); + return this; + } + + public Microwave bake() { + start(); + return deployClasspath(); + } + + public Microwave start() { + if (configuration.quickSession) { + tomcat = new TomcatWithFastSessionIDs(); + } else { + tomcat = new InternalTomcat(); + } + + { // setup + base = new File(getBaseDir()); + if (base.exists() && configuration.deleteBaseOnStartup) { + FileUtils.delete(base); + } else if (!base.exists()) { + FileUtils.mkDir(base); + } + + final File conf = createDirectory(base, "conf"); + createDirectory(base, "lib"); + createDirectory(base, "logs"); + createDirectory(base, "temp"); + createDirectory(base, "work"); + createDirectory(base, "webapps"); + + synchronize(conf, configuration.conf); + } + + final Properties props = configuration.properties; + StrSubstitutor substitutor = null; + for (final String s : props.stringPropertyNames()) { + final String v = props.getProperty(s); + if (v != null && v.contains("${")) { + if (substitutor == null) { + final Map<String, String> placeHolders = new HashMap<>(); + placeHolders.put("microwave.embedded.http", Integer.toString(configuration.httpPort)); + placeHolders.put("microwave.embedded.https", Integer.toString(configuration.httpsPort)); + placeHolders.put("microwave.embedded.stop", Integer.toString(configuration.stopPort)); + substitutor = new StrSubstitutor(placeHolders); + } + props.put(s, substitutor.replace(v)); + } + } + + final File conf = new File(base, "conf"); + final File webapps = new File(base, "webapps"); + + final boolean initialized; + if (configuration.serverXml != null) { + final File file = new File(conf, "server.xml"); + if (!file.equals(configuration.serverXml)) { + try (final InputStream is = new FileInputStream(configuration.serverXml); + final FileOutputStream fos = new FileOutputStream(file)) { + IOUtils.copy(is, fos); + } catch (final IOException e) { + throw new IllegalStateException(e); + } + } + + // respect config (host/port) of the Configuration + final QuickServerXmlParser ports = QuickServerXmlParser.parse(file); + if (configuration.keepServerXmlAsThis) { + configuration.httpPort = Integer.parseInt(ports.http()); + configuration.stopPort = Integer.parseInt(ports.stop()); + } else { + final Map<String, String> replacements = new HashMap<>(); + replacements.put(ports.http(), String.valueOf(configuration.httpPort)); + replacements.put(ports.https(), String.valueOf(configuration.httpsPort)); + replacements.put(ports.stop(), String.valueOf(configuration.stopPort)); + + String serverXmlContent; + try (final InputStream stream = new FileInputStream(file)) { + serverXmlContent = IOUtils.toString(stream, StandardCharsets.UTF_8); + for (final Map.Entry<String, String> pair : replacements.entrySet()) { + serverXmlContent = serverXmlContent.replace(pair.getKey(), pair.getValue()); + } + } catch (final IOException e) { + throw new IllegalStateException(e); + } + try (final OutputStream os = new FileOutputStream(file)) { + IOUtils.write(serverXmlContent, os); + } catch (final IOException e) { + throw new IllegalStateException(e); + } + } + + tomcat.server(createServer(file.getAbsolutePath())); + initialized = true; + } else { + initialized = false; + } + + tomcat.setBaseDir(base.getAbsolutePath()); + tomcat.setHostname(configuration.host); + if (!initialized) { + tomcat.getHost().setAppBase(webapps.getAbsolutePath()); + tomcat.getEngine().setDefaultHost(configuration.host); + tomcat.setHostname(configuration.host); + } + + if (configuration.realm != null) { + tomcat.getEngine().setRealm(configuration.realm); + } + + if (tomcat.getRawConnector() == null && !configuration.skipHttp) { + final Connector connector = createConnector(); + connector.setPort(configuration.httpPort); + if (connector.getAttribute("connectionTimeout") == null) { + connector.setAttribute("connectionTimeout", "3000"); + } + if (configuration.http2) { // would likely need SSLHostConfig programmatically + connector.addUpgradeProtocol(new Http2Protocol()); + } + + tomcat.getService().addConnector(connector); + tomcat.setConnector(connector); + } + + // create https connector + if (configuration.ssl) { + final Connector httpsConnector = createConnector(); + httpsConnector.setPort(configuration.httpsPort); + httpsConnector.setSecure(true); + httpsConnector.setProperty("SSLEnabled", "true"); + httpsConnector.setProperty("sslProtocol", configuration.sslProtocol); + + if (configuration.keystoreFile != null) { + httpsConnector.setAttribute("", configuration.keystoreFile); + } + if (configuration.keystorePass != null) { + httpsConnector.setAttribute("keystorePass", configuration.keystorePass); + } + httpsConnector.setAttribute("keystoreType", configuration.keystoreType); + if (configuration.clientAuth != null) { + httpsConnector.setAttribute("clientAuth", configuration.clientAuth); + } + if (configuration.keyAlias != null) { + httpsConnector.setAttribute("keyAlias", configuration.keyAlias); + } + + if (configuration.http2) { // would likely need SSLHostConfig programmatically + httpsConnector.addUpgradeProtocol(new Http2Protocol()); + } + + tomcat.getService().addConnector(httpsConnector); + + if (configuration.skipHttp) { + tomcat.setConnector(httpsConnector); + } + } + + for (final Connector c : configuration.connectors) { + tomcat.getService().addConnector(c); + } + if (!configuration.skipHttp && !configuration.ssl && !configuration.connectors.isEmpty()) { + tomcat.setConnector(configuration.connectors.iterator().next()); + } + + if (configuration.users != null) { + for (final Map.Entry<String, String> user : configuration.users.entrySet()) { + tomcat.addUser(user.getKey(), user.getValue()); + } + } + if (configuration.roles != null) { + for (final Map.Entry<String, String> user : configuration.roles.entrySet()) { + for (final String role : user.getValue().split(" *, *")) { + tomcat.addRole(user.getKey(), role); + } + } + } + + beforeStart(); + + try { + if (!initialized) { + tomcat.init(); + } + tomcat.start(); + } catch (final LifecycleException e) { + throw new IllegalStateException(e); + } + return this; + } + + protected void beforeStart() { + // no-op + } + + protected void beforeStop() { + // no-op + } + + @Override + public void close() { + if (tomcat == null) { + return; + } + beforeStop(); + try { + tomcat.stop(); + tomcat.destroy(); + } catch (final LifecycleException e) { + throw new IllegalStateException(e); + } finally { + FileUtils.delete(base); + } + } + + protected Connector createConnector() { + final Connector connector; + final Properties properties = configuration.properties; + if (properties != null) { + final Map<String, String> attributes = new HashMap<>(); + final ObjectRecipe recipe = new ObjectRecipe(Connector.class); + for (final String key : properties.stringPropertyNames()) { + if (!key.startsWith("connector.")) { + continue; + } + final String substring = key.substring("connector.".length()); + if (!substring.startsWith("attributes.")) { + recipe.setProperty(substring, properties.getProperty(key)); + } else { + attributes.put(substring.substring("attributes.".length()), properties.getProperty(key)); + } + } + connector = recipe.getProperties().isEmpty() ? new Connector() : Connector.class.cast(recipe.create()); + for (final Map.Entry<String, String> attr : attributes.entrySet()) { + connector.setAttribute(attr.getKey(), attr.getValue()); + } + } else { + connector = new Connector(); + } + return connector; + } + + private static Server createServer(final String serverXml) { + final Catalina catalina = new Catalina() { + // skip few init we don't need *here* + @Override + protected void initDirs() { + // no-op + } + + @Override + protected void initStreams() { + // no-op + } + + @Override + protected void initNaming() { + // no-op + } + }; + catalina.setConfigFile(serverXml); + catalina.load(); + return catalina.getServer(); + } + + private File createDirectory(final File parent, final String directory) { + final File dir = new File(parent, directory); + if (!dir.exists() && !dir.mkdirs()) { + throw new IllegalStateException("Unable to make dir " + dir.getAbsolutePath()); + } + + return dir; + } + + private void synchronize(final File base, final String resourceBase) { + if (resourceBase == null) { + return; + } + + try { + final Map<String, URL> urls = new ResourceFinder("").getResourcesMap(resourceBase); + for (final Map.Entry<String, URL> u : urls.entrySet()) { + try (final InputStream is = u.getValue().openStream()) { + final File to = new File(base, u.getKey()); + try (final OutputStream os = new FileOutputStream(to)) { + IOUtils.copy(is, os); + } + if ("server.xml".equals(u.getKey())) { + configuration.setServerXml(to.getAbsolutePath()); + } + } + } + } catch (final IOException e) { + throw new IllegalStateException(e); + } + } + + private String getBaseDir() { + File file; + try { + + final String dir = configuration.dir; + if (dir != null) { + final File dirFile = new File(dir); + if (dirFile.exists()) { + return dir; + } + FileUtils.mkDir(dirFile); + return dirFile.getAbsolutePath(); + } + + try { + final File target = new File("target"); + file = File.createTempFile("microwave", "-home", target.exists() ? target : null); + } catch (final Exception e) { + + final File tmp = new File(configuration.tempDir); + if (!tmp.exists() && !tmp.mkdirs()) { + throw new IOException("Failed to create local tmp directory: " + tmp.getAbsolutePath()); + } + + file = File.createTempFile("microwave", "-home", tmp); + } + + return file.getAbsolutePath(); + + } catch (final IOException e) { + throw new MicrowaveExplosion("Failed to get or create base dir: " + configuration.dir, e); + } + } + + @Data + @Accessors(fluent = true) + public static class Builder { + private int httpPort = 8080; + private int httpsPort = 8443; + private int stopPort = 8005; + private String host = "localhost"; + protected String dir; + private File serverXml; + private boolean keepServerXmlAsThis; + private Properties properties = new Properties(); + private boolean quickSession = true; + private boolean skipHttp; + private boolean ssl; + private String keystoreFile; + private String keystorePass; + private String keystoreType = "JKS"; + private String clientAuth; + private String keyAlias; + private String sslProtocol; + private String webXml; + private LoginConfigBuilder loginConfig; + private Collection<SecurityConstaintBuilder> securityConstraints = new LinkedList<>(); + private Realm realm; + private Map<String, String> users; + private Map<String, String> roles; + private boolean http2; + private final Collection<Connector> connectors = new ArrayList<>(); + private String tempDir = new File(System.getProperty("java.io.tmpdir"), "microwave_" + System.nanoTime()).getAbsolutePath(); + private boolean webResourceCached = true; + private String conf; + private boolean deleteBaseOnStartup = true; + private String jaxrsMapping = "/*"; + private boolean cdiConversation; + + public Builder() { // load defaults + loadFrom("microwave.properties"); + } + + public Builder randomHttpPort() { + try (final ServerSocket serverSocket = new ServerSocket(0)) { + this.httpPort = serverSocket.getLocalPort(); + } catch (final IOException e) { + throw new IllegalStateException(e); + } + return this; + } + + public Builder loadFrom(final String resource) { + try (final InputStream is = findStream(resource)) { + if (is != null) { + final Properties config = new Properties() {{ + load(is); + }}; + loadFromProperties(config); + } + return this; + } catch (final IOException e) { + throw new IllegalStateException(e); + } + } + + public void setServerXml(final String file) { + if (file == null) { + serverXml = null; + } else { + final File sXml = new File(file); + if (sXml.exists()) { + serverXml = sXml; + } + } + } + + public Builder property(final String key, final String value) { + properties.setProperty(key, value); + return this; + } + + private InputStream findStream(final String resource) throws FileNotFoundException { + InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource); + if (stream == null) { + final File file = new File(resource); + if (file.exists()) { + return new FileInputStream(file); + } + } + return stream; + } + + public Builder user(final String name, final String pwd) { + if (users == null) { + users = new HashMap<>(); + } + this.users.put(name, pwd); + return this; + } + + public Builder role(final String user, final String roles) { + if (this.roles == null) { + this.roles = new HashMap<>(); + } + this.roles.put(user, roles); + return this; + } + + public void addCustomizer(final ConfigurationCustomizer configurationCustomizer) { + configurationCustomizer.customize(this); + } + + public void loadFromProperties(final Properties config) { + // filtering properties with system properties or themself + final StrSubstitutor strSubstitutor = new StrSubstitutor(new StrLookup<String>() { + @Override + public String lookup(final String key) { + final String property = System.getProperty(key); + return property == null ? config.getProperty(key) : null; + } + }); + for (final String key : config.stringPropertyNames()) { + final String val = config.getProperty(key); + if (val == null || val.trim().isEmpty()) { + continue; + } + final String newVal = strSubstitutor.replace(config.getProperty(key)); + if (!val.equals(newVal)) { + config.setProperty(key, newVal); + } + } + + + final String http = config.getProperty("http"); + if (http != null) { + httpPort = Integer.parseInt(http); + } + final String https = config.getProperty("https"); + if (https != null) { + httpsPort = Integer.parseInt(https); + } + final String stop = config.getProperty("stop"); + if (stop != null) { + stopPort = Integer.parseInt(stop); + } + final String host = config.getProperty("host"); + if (host != null) { + this.host = host; + } + final String dir = config.getProperty("dir"); + if (dir != null) { + this.dir = dir; + } + final String serverXml = config.getProperty("serverXml"); + if (serverXml != null) { + setServerXml(serverXml); + } + final String keepServerXmlAsThis = config.getProperty("keepServerXmlAsThis"); + if (keepServerXmlAsThis != null) { + this.keepServerXmlAsThis = Boolean.parseBoolean(keepServerXmlAsThis); + } + final String quickSession = config.getProperty("quickSession"); + if (quickSession != null) { + this.quickSession = Boolean.parseBoolean(quickSession); + } + final String skipHttp = config.getProperty("skipHttp"); + if (skipHttp != null) { + this.skipHttp = Boolean.parseBoolean(skipHttp); + } + final String ssl = config.getProperty("ssl"); + if (ssl != null) { + this.ssl = Boolean.parseBoolean(ssl); + } + final String http2 = config.getProperty("http2"); + if (http2 != null) { + this.http2 = Boolean.parseBoolean(http2); + } + final String deleteBaseOnStartup = config.getProperty("deleteBaseOnStartup"); + if (deleteBaseOnStartup != null) { + this.deleteBaseOnStartup = Boolean.parseBoolean(deleteBaseOnStartup); + } + final String webResourceCached = config.getProperty("webResourceCached"); + if (webResourceCached != null) { + this.webResourceCached = Boolean.parseBoolean(webResourceCached); + } + final String keystoreFile = config.getProperty("keystoreFile"); + if (keystoreFile != null) { + this.keystoreFile = keystoreFile; + } + final String keystorePass = config.getProperty("keystorePass"); + if (keystorePass != null) { + this.keystorePass = keystorePass; + } + final String keystoreType = config.getProperty("keystoreType"); + if (keystoreType != null) { + this.keystoreType = keystoreType; + } + final String clientAuth = config.getProperty("clientAuth"); + if (clientAuth != null) { + this.clientAuth = clientAuth; + } + final String keyAlias = config.getProperty("keyAlias"); + if (keyAlias != null) { + this.keyAlias = keyAlias; + } + final String sslProtocol = config.getProperty("sslProtocol"); + if (sslProtocol != null) { + this.sslProtocol = sslProtocol; + } + final String webXml = config.getProperty("webXml"); + if (webXml != null) { + this.webXml = webXml; + } + final String tempDir = config.getProperty("tempDir"); + if (tempDir != null) { + this.tempDir = tempDir; + } + final String conf = config.getProperty("conf"); + if (conf != null) { + this.conf = conf; + } + for (final String prop : config.stringPropertyNames()) { + if (prop.startsWith("properties.")) { + property(prop.substring("properties.".length()), config.getProperty(prop)); + } else if (prop.startsWith("users.")) { + user(prop.substring("users.".length()), config.getProperty(prop)); + } else if (prop.startsWith("roles.")) { + role(prop.substring("roles.".length()), config.getProperty(prop)); + } else if (prop.startsWith("connector.")) { // created in container + property(prop, config.getProperty(prop)); + } else if (prop.equals("realm")) { + final ObjectRecipe recipe = new ObjectRecipe(config.getProperty(prop)); + for (final String realmConfig : config.stringPropertyNames()) { + if (realmConfig.startsWith("realm.")) { + recipe.setProperty(realmConfig.substring("realm.".length()), config.getProperty(realmConfig)); + } + } + this.realm = Realm.class.cast(recipe.create()); + } else if (prop.equals("login")) { + final ObjectRecipe recipe = new ObjectRecipe(LoginConfigBuilder.class.getName()); + for (final String nestedConfig : config.stringPropertyNames()) { + if (nestedConfig.startsWith("login.")) { + recipe.setProperty(nestedConfig.substring("login.".length()), config.getProperty(nestedConfig)); + } + } + loginConfig = LoginConfigBuilder.class.cast(recipe.create()); + } else if (prop.equals("securityConstraint")) { + final ObjectRecipe recipe = new ObjectRecipe(SecurityConstaintBuilder.class.getName()); + for (final String nestedConfig : config.stringPropertyNames()) { + if (nestedConfig.startsWith("securityConstraint.")) { + recipe.setProperty(nestedConfig.substring("securityConstraint.".length()), config.getProperty(nestedConfig)); + } + } + securityConstraints.add(SecurityConstaintBuilder.class.cast(recipe.create())); + } else if (prop.equals("configurationCustomizer.")) { + final String next = prop.substring("configurationCustomizer.".length()); + if (next.contains(".")) { + continue; + } + final ObjectRecipe recipe = new ObjectRecipe(properties.getProperty(prop + ".class")); + for (final String nestedConfig : config.stringPropertyNames()) { + if (nestedConfig.startsWith(prop) && !prop.endsWith(".class")) { + recipe.setProperty(nestedConfig.substring(prop.length() + 1 /*dot*/), config.getProperty(nestedConfig)); + } + } + addCustomizer(ConfigurationCustomizer.class.cast(recipe.create())); + } + } + } + } + + public static class LoginConfigBuilder { + private final LoginConfig loginConfig = new LoginConfig(); + + public void setErrorPage(final String errorPage) { + loginConfig.setErrorPage(errorPage); + } + + public void setLoginPage(final String loginPage) { + loginConfig.setLoginPage(loginPage); + } + + public void setRealmName(final String realmName) { + loginConfig.setRealmName(realmName); + } + + public void setAuthMethod(final String authMethod) { + loginConfig.setAuthMethod(authMethod); + } + + public LoginConfigBuilder errorPage(final String errorPage) { + loginConfig.setErrorPage(errorPage); + return this; + } + + public LoginConfigBuilder loginPage(final String loginPage) { + loginConfig.setLoginPage(loginPage); + return this; + } + + public LoginConfigBuilder realmName(final String realmName) { + loginConfig.setRealmName(realmName); + return this; + } + + public LoginConfigBuilder authMethod(final String authMethod) { + loginConfig.setAuthMethod(authMethod); + return this; + } + + public LoginConfig build() { + return loginConfig; + } + + public LoginConfigBuilder basic() { + return authMethod("BASIC"); + } + + public LoginConfigBuilder digest() { + return authMethod("DIGEST"); + } + + public LoginConfigBuilder clientCert() { + return authMethod("CLIENT-CERT"); + } + + public LoginConfigBuilder form() { + return authMethod("FORM"); + } + } + + public static class SecurityConstaintBuilder { + private final SecurityConstraint securityConstraint = new SecurityConstraint(); + + public SecurityConstaintBuilder authConstraint(final boolean authConstraint) { + securityConstraint.setAuthConstraint(authConstraint); + return this; + } + + public SecurityConstaintBuilder displayName(final String displayName) { + securityConstraint.setDisplayName(displayName); + return this; + } + + public SecurityConstaintBuilder userConstraint(final String constraint) { + securityConstraint.setUserConstraint(constraint); + return this; + } + + public SecurityConstaintBuilder addAuthRole(final String authRole) { + securityConstraint.addAuthRole(authRole); + return this; + } + + public SecurityConstaintBuilder addCollection(final String name, final String pattern, final String... methods) { + final SecurityCollection collection = new SecurityCollection(); + collection.setName(name); + collection.addPattern(pattern); + for (final String httpMethod : methods) { + collection.addMethod(httpMethod); + } + securityConstraint.addCollection(collection); + return this; + } + + public void setAuthConstraint(final boolean authConstraint) { + securityConstraint.setAuthConstraint(authConstraint); + } + + public void setDisplayName(final String displayName) { + securityConstraint.setDisplayName(displayName); + } + + public void setUserConstraint(final String userConstraint) { + securityConstraint.setUserConstraint(userConstraint); + } + + public void setAuthRole(final String authRole) { // easier for config + addAuthRole(authRole); + } + + // name:pattern:method1/method2 + public void setCollection(final String value) { // for config + final String[] split = value.split(":"); + if (split.length != 3 && split.length != 2) { + throw new IllegalArgumentException("Can't parse " + value + ", syntax is: name:pattern:method1/method2"); + } + addCollection(split[0], split[1], split.length == 2 ? new String[0] : split[2].split("/")); + } + + public SecurityConstraint build() { + return securityConstraint; + } + } + + public interface ConfigurationCustomizer { + void customize(Builder configuration); + } + + private static class InternalTomcat extends Tomcat { + private void server(final Server s) { + server = s; + if (service == null) { + final Service[] services = server.findServices(); + if (services.length > 0) { + service = services[0]; + if (service.getContainer() != null) { + engine = Engine.class.cast(service.getContainer()); + final org.apache.catalina.Container[] hosts = engine.findChildren(); + if (hosts.length > 0) { + host = Host.class.cast(hosts[0]); + } + } + } + if (service.findConnectors().length > 0) { + connector = service.findConnectors()[0]; + } + } + } + + public Connector getRawConnector() { + return connector; + } + } + + private static class TomcatWithFastSessionIDs extends InternalTomcat { + @Override + public void start() throws LifecycleException { + // Use fast, insecure session ID generation for all tests + final Server server = getServer(); + for (final Service service : server.findServices()) { + final org.apache.catalina.Container e = service.getContainer(); + for (final org.apache.catalina.Container h : e.findChildren()) { + for (final org.apache.catalina.Container c : h.findChildren()) { + Manager m = ((org.apache.catalina.Context) c).getManager(); + if (m == null) { + m = new StandardManager(); + org.apache.catalina.Context.class.cast(c).setManager(m); + } + if (m instanceof ManagerBase) { + ManagerBase.class.cast(m).setSecureRandomClass( + "org.apache.catalina.startup.FastNonSecureRandom"); + } + } + } + } + super.start(); + } + } + + private static class QuickServerXmlParser extends DefaultHandler { + private static final SAXParserFactory FACTORY = SAXParserFactory.newInstance(); + + static { + FACTORY.setNamespaceAware(true); + FACTORY.setValidating(false); + } + + private static final String STOP_KEY = "STOP"; + private static final String HTTP_KEY = "HTTP"; + private static final String SECURED_SUFFIX = "S"; + private static final String AJP_KEY = "AJP"; + private static final String HOST_KEY = "host"; + private static final String APP_BASE_KEY = "app-base"; + private static final String DEFAULT_CONNECTOR_KEY = HTTP_KEY; + private static final String KEYSTORE_KEY = "keystoreFile"; + + public static final String DEFAULT_HTTP_PORT = "8080"; + public static final String DEFAULT_HTTPS_PORT = "8443"; + public static final String DEFAULT_STOP_PORT = "8005"; + public static final String DEFAULT_AJP_PORT = "8009"; + public static final String DEFAULT_HOST = "localhost"; + public static final String DEFAULT_APP_BASE = "webapps"; + public static final String DEFAULT_KEYSTORE = null; + + private final Map<String, String> values = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER); + + public QuickServerXmlParser() { // ensure defaults are present + this(true); + } + + public QuickServerXmlParser(final boolean useDefaults) { + if (useDefaults) { + values.put(STOP_KEY, DEFAULT_STOP_PORT); + values.put(HTTP_KEY, DEFAULT_HTTP_PORT); + values.put(AJP_KEY, DEFAULT_AJP_PORT); + values.put(HOST_KEY, DEFAULT_HOST); + values.put(APP_BASE_KEY, DEFAULT_APP_BASE); + values.put(KEYSTORE_KEY, DEFAULT_KEYSTORE); + } + } + + @Override + public void startElement(final String uri, final String localName, + final String qName, final Attributes attributes) throws SAXException { + if ("Server".equalsIgnoreCase(localName)) { + final String port = attributes.getValue("port"); + if (port != null) { + values.put(STOP_KEY, port); + } else { + values.put(STOP_KEY, DEFAULT_STOP_PORT); + } + } else if ("Connector".equalsIgnoreCase(localName)) { + String protocol = attributes.getValue("protocol"); + if (protocol == null) { + protocol = DEFAULT_CONNECTOR_KEY; + } else if (protocol.contains("/")) { + protocol = protocol.substring(0, protocol.indexOf("/")); + } + final String port = attributes.getValue("port"); + final String ssl = attributes.getValue("secure"); + + if (ssl == null || "false".equalsIgnoreCase(ssl)) { + values.put(protocol.toUpperCase(), port); + } else { + values.put(protocol.toUpperCase() + SECURED_SUFFIX, port); + } + + final String keystore = attributes.getValue("keystoreFile"); + if (null != keystore) { + values.put(KEYSTORE_KEY, keystore); + } + } else if ("Host".equalsIgnoreCase(localName)) { + final String host = attributes.getValue("name"); + if (host != null) { + values.put(HOST_KEY, host); + } + + final String appBase = attributes.getValue("appBase"); + if (appBase != null) { + values.put(APP_BASE_KEY, appBase); + } + } + } + + public static QuickServerXmlParser parse(final File serverXml) { + return parse(serverXml, true); + } + + public static QuickServerXmlParser parse(final File serverXml, final boolean defaults) { + final QuickServerXmlParser handler = new QuickServerXmlParser(defaults); + try { + final SAXParser parser = FACTORY.newSAXParser(); + parser.parse(serverXml, handler); + } catch (final Exception e) { + // no-op: using defaults + } + return handler; + } + + public static QuickServerXmlParser parse(final String serverXmlContents) { + final QuickServerXmlParser handler = new QuickServerXmlParser(); + try { + final SAXParser parser = FACTORY.newSAXParser(); + parser.parse(new ByteArrayInputStream(serverXmlContents.getBytes()), handler); + } catch (final Exception e) { + // no-op: using defaults + } + return handler; + } + + public String http() { + return value(HTTP_KEY, DEFAULT_HTTP_PORT); + } + + public String https() { // enough common to be exposed as method + return securedValue(HTTP_KEY, DEFAULT_HTTPS_PORT); + } + + public String ajp() { + return value(AJP_KEY, DEFAULT_AJP_PORT); + } + + public String stop() { + return value(STOP_KEY, DEFAULT_STOP_PORT); + } + + public String appBase() { + return value(APP_BASE_KEY, DEFAULT_APP_BASE); + } + + public String host() { + return value(HOST_KEY, DEFAULT_HOST); + } + + public String keystore() { + return value(KEYSTORE_KEY, DEFAULT_KEYSTORE); + } + + public String value(final String key, final String defaultValue) { + final String val = values.get(key); + if (val == null) { + return defaultValue; + } + return val; + } + + public String securedValue(final String key, final String defaultValue) { + return value(key + SECURED_SUFFIX, defaultValue); + } + + @Override + public String toString() { + return "QuickServerXmlParser: " + values; + } + } + +} Added: openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/MicrowaveExplosion.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/MicrowaveExplosion.java?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/MicrowaveExplosion.java (added) +++ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/MicrowaveExplosion.java Tue Oct 18 21:12:40 2016 @@ -0,0 +1,25 @@ +/* + * 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.microwave; + +public class MicrowaveExplosion extends RuntimeException { + public MicrowaveExplosion(final String msg, final Exception e) { + super(msg, e); + } +} Added: openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/BusInstance.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/BusInstance.java?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/BusInstance.java (added) +++ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/BusInstance.java Tue Oct 18 21:12:40 2016 @@ -0,0 +1,33 @@ +/* + * 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.microwave.cxf; + +import lombok.experimental.Delegate; +import org.apache.cxf.Bus; +import org.apache.cxf.bus.extension.ExtensionManagerBus; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Named; + +@Named("cxf") +@ApplicationScoped +public class BusInstance implements Bus { + @Delegate + private Bus delegate = new ExtensionManagerBus(); +} Added: openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/CxfCdiAutoSetup.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/CxfCdiAutoSetup.java?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/CxfCdiAutoSetup.java (added) +++ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/CxfCdiAutoSetup.java Tue Oct 18 21:12:40 2016 @@ -0,0 +1,72 @@ +/* + * 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.microwave.cxf; + +import org.apache.cxf.cdi.CXFCdiServlet; +import org.apache.cxf.jaxrs.provider.ServerProviderFactory; +import org.apache.cxf.transport.ChainInitiationObserver; +import org.apache.johnzon.jaxrs.DelegateProvider; +import org.apache.johnzon.jaxrs.JohnzonProvider; +import org.apache.johnzon.jaxrs.JsrProvider; +import org.apache.microwave.Microwave; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletContainerInitializer; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRegistration; +import java.util.List; +import java.util.Set; + +import static java.util.Arrays.asList; + +public class CxfCdiAutoSetup implements ServletContainerInitializer { + @Override + public void onStartup(final Set<Class<?>> c, final ServletContext ctx) throws ServletException { + final Microwave.Builder builder = Microwave.Builder.class.cast(ctx.getAttribute("microwave.configuration")); + final ServletRegistration.Dynamic jaxrs = ctx.addServlet("cxf-cdi", new CXFCdiServlet() { + @Override + protected void loadBus(final ServletConfig servletConfig) { + super.loadBus(servletConfig); + if (!"true".equalsIgnoreCase(builder.properties().getProperty("microwave.jaxrs.providers.setup", "true"))) { + return; + } + + final List<DelegateProvider<?>> providers = asList(new JohnzonProvider<>(), new JsrProvider()); + + // client + if (bus.getProperty("org.apache.cxf.jaxrs.bus.providers") == null) { + bus.setProperty("skip.default.json.provider.registration", "true"); + bus.setProperty("org.apache.cxf.jaxrs.bus.providers", providers); + } + + // server + getDestinationRegistryFromBus().getDestinations() + .forEach(d -> { + final ChainInitiationObserver observer = ChainInitiationObserver.class.cast(d.getMessageObserver()); + final ServerProviderFactory providerFactory = ServerProviderFactory.class.cast(observer.getEndpoint().get(ServerProviderFactory.class.getName())); + providerFactory.setUserProviders(providers); + }); + } + }); + jaxrs.setLoadOnStartup(1); + jaxrs.setAsyncSupported(true); + jaxrs.addMapping(builder.jaxrsMapping()); + } +} Added: openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/JAXRSCdiResourceExtensionWorkaround.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/JAXRSCdiResourceExtensionWorkaround.java?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/JAXRSCdiResourceExtensionWorkaround.java (added) +++ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/JAXRSCdiResourceExtensionWorkaround.java Tue Oct 18 21:12:40 2016 @@ -0,0 +1,41 @@ +/* + * 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.microwave.cxf; + +import org.apache.cxf.Bus; +import org.apache.cxf.BusFactory; +import org.apache.cxf.cdi.JAXRSCdiResourceExtension; + +import javax.enterprise.event.Observes; +import javax.enterprise.inject.spi.AfterDeploymentValidation; +import javax.enterprise.inject.spi.BeanManager; + +// just there to ensure we use a single bus even for ResourceUtils.createApplication, should be removed with 3.1.9 hopefully +public class JAXRSCdiResourceExtensionWorkaround extends JAXRSCdiResourceExtension { + @Override + public void load(@Observes final AfterDeploymentValidation event, final BeanManager beanManager) { + final Bus bus = Bus.class.cast(beanManager.getReference(beanManager.resolve(beanManager.getBeans(Bus.class)), Bus.class, null)); + BusFactory.setThreadDefaultBus(bus); // cause app class will rely on that and would create multiple bus and then deployment would be broken + try { + super.load(event, beanManager); + } finally { + BusFactory.clearDefaultBusForAnyThread(bus); + } + } +} Added: openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/openwebbeans/MicrowaveLoader.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/openwebbeans/MicrowaveLoader.java?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/openwebbeans/MicrowaveLoader.java (added) +++ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/openwebbeans/MicrowaveLoader.java Tue Oct 18 21:12:40 2016 @@ -0,0 +1,52 @@ +/* + * 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.microwave.openwebbeans; + +import org.apache.cxf.cdi.JAXRSCdiResourceExtension; +import org.apache.webbeans.service.DefaultLoaderService; +import org.apache.webbeans.spi.LoaderService; + +import javax.enterprise.inject.spi.Extension; +import java.util.Iterator; +import java.util.List; + +// just there to get rid of the original cxf extension, to remove with 3.1.9 hopefully +public class MicrowaveLoader implements LoaderService { + private final LoaderService defaultService = new DefaultLoaderService(); + + @Override + public <T> List<T> load(final Class<T> serviceType) { + return defaultService.load(serviceType); + } + + @Override + public <T> List<T> load(final Class<T> serviceType, final ClassLoader classLoader) { + final List<T> load = defaultService.load(serviceType, classLoader); + if (Extension.class == serviceType) { + final Iterator<T> e = load.iterator(); + while (e.hasNext()) { + if (JAXRSCdiResourceExtension.class == e.next().getClass()) { + e.remove(); + break; + } + } + } + return load; + } +} Added: openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/openwebbeans/OWBAutoSetup.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/openwebbeans/OWBAutoSetup.java?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/openwebbeans/OWBAutoSetup.java (added) +++ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/openwebbeans/OWBAutoSetup.java Tue Oct 18 21:12:40 2016 @@ -0,0 +1,43 @@ +/* + * 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.microwave.openwebbeans; + +import org.apache.microwave.Microwave; +import org.apache.webbeans.servlet.WebBeansConfigurationListener; +import org.apache.webbeans.web.context.WebConversationFilter; + +import javax.servlet.DispatcherType; +import javax.servlet.FilterRegistration; +import javax.servlet.ServletContainerInitializer; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import java.util.EnumSet; +import java.util.Set; + +public class OWBAutoSetup implements ServletContainerInitializer { + @Override + public void onStartup(final Set<Class<?>> c, final ServletContext ctx) throws ServletException { + final Microwave.Builder builder = Microwave.Builder.class.cast(ctx.getAttribute("microwave.configuration")); + if (builder.cdiConversation()) { + final FilterRegistration.Dynamic filter = ctx.addFilter("owb-conversation", WebConversationFilter.class); + filter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*"); + } + ctx.addListener(WebBeansConfigurationListener.class); + } +} Added: openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/tomcat/ProvidedLoader.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/tomcat/ProvidedLoader.java?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/tomcat/ProvidedLoader.java (added) +++ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/tomcat/ProvidedLoader.java Tue Oct 18 21:12:40 2016 @@ -0,0 +1,89 @@ +/* + * 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.microwave.tomcat; + +import org.apache.catalina.Context; +import org.apache.catalina.Loader; + +import java.beans.PropertyChangeListener; + +public class ProvidedLoader implements Loader { + private final ClassLoader delegate; + private Context context; + + public ProvidedLoader(final ClassLoader loader) { + this.delegate = loader == null ? ClassLoader.getSystemClassLoader() : loader; + } + + @Override + public void backgroundProcess() { + // no-op + } + + @Override + public ClassLoader getClassLoader() { + return delegate; + } + + @Override + public Context getContext() { + return context; + } + + @Override + public void setContext(final Context context) { + this.context = context; + } + + @Override + public boolean modified() { + return false; + } + + @Override + public boolean getDelegate() { + return false; + } + + @Override + public void setDelegate(final boolean delegate) { + // ignore + } + + @Override + public boolean getReloadable() { + return false; + } + + @Override + public void setReloadable(final boolean reloadable) { + // no-op + } + + @Override + public void addPropertyChangeListener(final PropertyChangeListener listener) { + // no-op + } + + @Override + public void removePropertyChangeListener(final PropertyChangeListener listener) { + // no-op + } +} + Added: openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/beans.xml URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/beans.xml?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/beans.xml (added) +++ openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/beans.xml Tue Oct 18 21:12:40 2016 @@ -0,0 +1,19 @@ +<!-- + 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. +--> +<beans /> Added: openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/openwebbeans/openwebbeans.properties URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/openwebbeans/openwebbeans.properties?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/openwebbeans/openwebbeans.properties (added) +++ openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/openwebbeans/openwebbeans.properties Tue Oct 18 21:12:40 2016 @@ -0,0 +1,91 @@ +#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. +configuration.ordinal=1000 +org.apache.webbeans.spi.LoaderService=org.apache.microwave.openwebbeans.MicrowaveLoader +org.apache.webbeans.scanExclusionPaths=\ + /jre/lib, \ + /Contents/Home/, \ + /dt.jar, \ + /tools.jar, \ + /bootstrap.jar, \ + /asm, \ + /javassist, \ + /xbean-, \ + /jconsole.jar, \ + /geronimo-, \ + /commons-, \ + /arquillian-, \ + /bsh-, \ + /shrinkwrap-, \ + /junit-, \ + /testng-, \ + /openjpa-, \ + /bcel, \ + /hamcrest, \ + /mysql-connector, \ + /testng, \ + /idea_rt, \ + /eclipse, \ + /jcommander, \ + /tomcat, \ + /catalina, \ + /jasper, \ + /jsp-api, \ + /myfaces-api, \ + /myfaces-impl, \ + /servlet-api, \ + /javax, \ + /annotation-api, \ + /el-api, \ + /mojarra, \ + /sisu-guice-, \ + /sisu-inject-, \ + /aether-, \ + /plexus-, \ + /maven-, \ + /guava-, \ + /openwebbeans-, \ + /bcprov-jdk14-, \ + /bcmail-jdk14-, \ + /bctsp-jdk14-, \ + /bcmail-jdk14-, \ + /ss_css2-, \ + /itext-, \ + /pd4ml-, \ + /xmlpull-, \ + /log4j-, \ + /slf4j-, \ + /logkit, \ + /gson-, \ + /xstream-, \ + /httpclient-, \ + /httpcore-, \ + /backport-util-concurrent-, \ + /xml-apis, \ + /xpp3_min-, \ + /bval-core, \ + /bval-jsr, \ + /hsqldb, \ + /quartz-2, \ + /jetty-, \ + /plexus-,\ + /johnzon-,\ + /cxf-,\ + /woodstox-,\ + /stax,\ + /xmlschema,\ + /lombok Added: openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension (added) +++ openwebbeans/microwave/trunk/microwave-core/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension Tue Oct 18 21:12:40 2016 @@ -0,0 +1 @@ +org.apache.microwave.cxf.JAXRSCdiResourceExtensionWorkaround Added: openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/MicrowaveTest.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/MicrowaveTest.java?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/MicrowaveTest.java (added) +++ openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/MicrowaveTest.java Tue Oct 18 21:12:40 2016 @@ -0,0 +1,79 @@ +/* + * 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.microwave; + +import org.apache.commons.io.IOUtils; +import org.apache.cxf.helpers.FileUtils; +import org.apache.microwave.app.Endpoint; +import org.apache.microwave.app.RsApp; +import org.junit.Test; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.util.stream.Stream; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class MicrowaveTest { + @Test + public void simpleWebapp() { + final File root = new File("target/MicrowaveTest/simpleWebapp/app"); + FileUtils.mkDir(root); + Stream.of(Endpoint.class, RsApp.class).forEach(type -> { + final String target = type.getName().replace(".", "/"); + File targetFile = new File(root, "WEB-INF/classes/" + target + ".class"); + FileUtils.mkDir(targetFile.getParentFile()); + try (final InputStream from = Thread.currentThread().getContextClassLoader().getResourceAsStream(target + ".class"); + final OutputStream to = new FileOutputStream(targetFile)) { + IOUtils.copy(from, to); + } catch (final IOException e) { + fail(); + } + }); + try (final Microwave microwave = new Microwave(new Microwave.Builder().randomHttpPort()).start()) { + microwave.deployWebapp("", root); + assertEquals("simple", IOUtils.toString(new URL("http://localhost:" + microwave.getConfiguration().httpPort() + "/api/test"))); + } catch (final IOException e) { + fail(e.getMessage()); + } + } + + @Test + public void classpath() { + try (final Microwave microwave = new Microwave(new Microwave.Builder().randomHttpPort()).bake()) { + assertEquals("simple", IOUtils.toString(new URL("http://localhost:" + microwave.getConfiguration().httpPort() + "/api/test"))); + } catch (final IOException e) { + fail(e.getMessage()); + } + } + + @Test + public void json() { + try (final Microwave microwave = new Microwave(new Microwave.Builder().randomHttpPort()).bake()) { + assertEquals("{\"name\":\"test\"}", IOUtils.toString(new URL("http://localhost:" + microwave.getConfiguration().httpPort() + "/api/test/json"))); + } catch (final IOException e) { + fail(e.getMessage()); + } + } +} Added: openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/app/Endpoint.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/app/Endpoint.java?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/app/Endpoint.java (added) +++ openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/app/Endpoint.java Tue Oct 18 21:12:40 2016 @@ -0,0 +1,53 @@ +/* + * 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.microwave.app; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.enterprise.context.ApplicationScoped; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +@Path("test") +@ApplicationScoped +public class Endpoint { + @GET + @Produces(MediaType.TEXT_PLAIN) + public String simple() { + return "simple"; + } + + @GET + @Path("json") + @Produces(MediaType.APPLICATION_JSON) + public Simple json() { + return new Simple("test"); + } + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class Simple { + private String name; + } +} Added: openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/app/RsApp.java URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/app/RsApp.java?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/app/RsApp.java (added) +++ openwebbeans/microwave/trunk/microwave-core/src/test/java/org/apache/microwave/app/RsApp.java Tue Oct 18 21:12:40 2016 @@ -0,0 +1,28 @@ +/* + * 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.microwave.app; + +import javax.enterprise.context.Dependent; +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; + +@Dependent +@ApplicationPath("api") +public class RsApp extends Application { +} Added: openwebbeans/microwave/trunk/microwave-maven-plugin/pom.xml URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-maven-plugin/pom.xml?rev=1765511&view=auto ============================================================================== --- openwebbeans/microwave/trunk/microwave-maven-plugin/pom.xml (added) +++ openwebbeans/microwave/trunk/microwave-maven-plugin/pom.xml Tue Oct 18 21:12:40 2016 @@ -0,0 +1,95 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://maven.apache.org/POM/4.0.0 + http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>microwave</artifactId> + <groupId>org.apache.microwave</groupId> + <version>0.0.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>microwave-maven-plugin</artifactId> + <name>Microwave :: Maven</name> + + <properties> + <maven.version>3.0</maven.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>${maven.version}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>${maven.version}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.plugin-tools</groupId> + <artifactId>maven-plugin-annotations</artifactId> + <version>3.3</version> + </dependency> + + <dependency> + <groupId>org.apache.microwave</groupId> + <artifactId>microwave-core</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-plugin-plugin</artifactId> + <version>3.4</version> + <executions> + <execution> + <id>mojo-descriptor</id> + <goals> + <goal>descriptor</goal> + <goal>helpmojo</goal> + </goals> + </execution> + </executions> + <configuration> + <goalPrefix>microwave</goalPrefix> + <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound> + </configuration> + </plugin> + </plugins> + </build> + + <reporting> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-plugin-plugin</artifactId> + <version>${maven.version}</version> + </plugin> + </plugins> + </reporting> +</project>