1. Stephen McKamey
  2. duel

Commits

Stephen McKamey  committed 85fd2f8

adding maven plugin for generating static site from DUEL-based WAR

  • Participants
  • Parent commits c9ec72a
  • Branches default

Comments (0)

Files changed (16)

File .hgignore

View file
  • Ignore whitespace
 duel-js/src/test/resources/ga.js
 duel-maven-plugin/target
 duel-staticapps/target
+duel-staticapps-maven-plugin/target
 target
 TODO.txt

File deploy.sh

View file
  • Ignore whitespace
 
 cd duel-staticapps
 mvn clean deploy -U -DperformRelease=true -Dgpg.keyname=EE82F9AB
+
+cd duel-staticapps-maven-plugin
+mvn clean deploy -U -DperformRelease=true -Dgpg.keyname=EE82F9AB

File duel-compiler/pom.xml

View file
  • Ignore whitespace
 
 	<groupId>org.duelengine</groupId>
 	<artifactId>duel-compiler</artifactId>
-	<version>0.8.1</version>
+	<version>0.8.2</version>
 	<packaging>jar</packaging>
 
 	<name>DUEL Compiler</name>

File duel-js/pom.xml

View file
  • Ignore whitespace
 
 	<groupId>org.duelengine</groupId>
 	<artifactId>duel-js</artifactId>
-	<version>0.8.1</version>
+	<version>0.8.2</version>
 	<packaging>pom</packaging>
 
 	<name>DUEL Client Scripts</name>

File duel-js/target/duel.js

View file
  • Ignore whitespace
 /*global window */
 
 /**
- * @license DUEL v0.8.1 http://duelengine.org
+ * @license DUEL v0.8.2 http://duelengine.org
  * Copyright (c)2006-2012 Stephen M. McKamey.
  * Licensed under The MIT License.
  */

File duel-js/target/duel.min.js

View file
  • Ignore whitespace
 /*
- DUEL v0.8.1 http://duelengine.org
+ DUEL v0.8.2 http://duelengine.org
  Copyright (c)2006-2012 Stephen M. McKamey.
  Licensed under The MIT License.
 */

File duel-maven-plugin/pom.xml

View file
  • Ignore whitespace
 
 	<groupId>org.duelengine</groupId>
 	<artifactId>duel-maven-plugin</artifactId>
-	<version>0.8.1</version>
+	<version>0.8.2</version>
 	<packaging>maven-plugin</packaging>
 
 	<name>DUEL Maven Plugin</name>

File duel-staticapps-maven-plugin/pom.xml

View file
  • Ignore whitespace
+<?xml version="1.0"?>
+<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">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.sonatype.oss</groupId>
+		<artifactId>oss-parent</artifactId>
+		<version>7</version>
+		<relativePath></relativePath>
+	</parent>
+
+	<groupId>org.duelengine</groupId>
+	<artifactId>duel-staticapps-maven-plugin</artifactId>
+	<version>0.8.2</version>
+	<packaging>maven-plugin</packaging>
+
+	<name>DUEL Static Apps Maven Plugin</name>
+	<description>Maven Plugin for DUEL Static Site Generator</description>
+	<url>http://duelengine.org</url>
+	<licenses>
+		<license>
+			<name>MIT License</name>
+			<url>http://duelengine.org/LICENSE.txt</url>
+		</license>
+	</licenses>
+	<scm>
+		<url>https://bitbucket.org/mckamey/duel</url>
+		<connection>scm:hg:https://bitbucket.org/mckamey/duel</connection>
+		<developerConnection>scm:hg:https://bitbucket.org/mckamey/duel</developerConnection>
+	</scm>
+	<developers>
+		<developer>
+			<id>mckamey</id>
+			<name>Stephen M. McKamey</name>
+			<url>http://mck.me</url>
+		</developer>
+	</developers>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+
+		<slf4j.version>1.6.4</slf4j.version>
+		<maven.version>3.0.4</maven.version>
+		<junit.version>4.9</junit.version>
+		<jvm.version>1.6</jvm.version>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.duelengine</groupId>
+			<artifactId>duel-staticapps</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-api</artifactId>
+			<version>${slf4j.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.maven</groupId>
+			<artifactId>maven-core</artifactId>
+			<version>${maven.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.maven</groupId>
+			<artifactId>maven-plugin-api</artifactId>
+			<version>${maven.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>${junit.version}</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-plugin-plugin</artifactId>
+				<version>2.9</version>
+				<executions>
+					<execution>
+						<id>generated-helpmojo</id>
+						<goals>
+							<goal>helpmojo</goal>
+						</goals>
+					</execution>
+				</executions>
+				<configuration>
+					<goalPrefix>duel</goalPrefix>
+				</configuration>
+			</plugin>
+		</plugins>
+		<pluginManagement>
+			<plugins>
+				<plugin>
+					<artifactId>maven-compiler-plugin</artifactId>
+					<version>2.3.2</version>
+					<configuration>
+						<source>${jvm.version}</source>
+						<target>${jvm.version}</target>
+					</configuration>
+				</plugin>
+				<plugin>
+					<artifactId>maven-surefire-plugin</artifactId>
+					<version>2.7.2</version>
+				</plugin>
+			</plugins>
+		</pluginManagement>
+	</build>
+
+	<profiles>
+		<profile>
+			<id>release-sign-artifacts</id>
+			<activation>
+				<property>
+					<name>performRelease</name>
+					<value>true</value>
+				</property>
+			</activation>
+			<build>
+				<plugins>
+					<plugin>
+						<groupId>org.apache.maven.plugins</groupId>
+						<artifactId>maven-gpg-plugin</artifactId>
+						<version>1.4</version>
+						<executions>
+							<execution>
+								<id>sign-artifacts</id>
+								<phase>verify</phase>
+								<goals>
+									<goal>sign</goal>
+								</goals>
+							</execution>
+						</executions>
+					</plugin>
+				</plugins>
+			</build>
+		</profile>
+	</profiles>
+</project>

File duel-staticapps-maven-plugin/src/main/java/org/duelengine/duel/staticapps/maven/MavenLoggerAdapter.java

View file
  • Ignore whitespace
+package org.duelengine.duel.staticapps.maven;
+
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugin.logging.SystemStreamLog;
+import org.slf4j.helpers.MarkerIgnoringBase;
+
+@SuppressWarnings("serial")
+class MavenLoggerAdapter extends MarkerIgnoringBase {
+
+	private final Log log;
+
+	public MavenLoggerAdapter(String name, Log log) {
+		this.name = name;
+		this.log = (log != null) ? log : new SystemStreamLog();
+	}
+
+	protected Log getLog() {
+		return log;
+	}
+	
+	@Override
+	public void debug(String msg) {
+		getLog().debug(msg);
+	}
+
+	@Override
+	public void debug(String format, Object arg1) {
+		debug(String.format(format, arg1));
+	}
+
+	@Override
+	public void debug(String format, Object[] arg1) {
+		debug(String.format(format, arg1));
+	}
+
+	@Override
+	public void debug(String msg, Throwable t) {
+		getLog().debug(msg, t);
+	}
+
+	@Override
+	public void debug(String format, Object arg1, Object arg2) {
+		debug(String.format(format, arg1, arg2));
+	}
+
+	@Override
+	public void error(String msg) {
+		getLog().error(msg);
+	}
+
+	@Override
+	public void error(String format, Object arg1) {
+		error(String.format(format, arg1));
+	}
+
+	@Override
+	public void error(String format, Object[] arg1) {
+		error(String.format(format, arg1));
+	}
+
+	@Override
+	public void error(String msg, Throwable t) {
+		getLog().error(msg, t);
+	}
+
+	@Override
+	public void error(String format, Object arg1, Object arg2) {
+		error(String.format(format, arg1, arg2));
+	}
+
+	@Override
+	public void info(String msg) {
+		getLog().info(msg);
+	}
+
+	@Override
+	public void info(String format, Object arg1) {
+		info(String.format(format, arg1));
+	}
+
+	@Override
+	public void info(String format, Object[] arg1) {
+		info(String.format(format, arg1));
+	}
+
+	@Override
+	public void info(String msg, Throwable t) {
+		getLog().info(msg, t);
+	}
+
+	@Override
+	public void info(String format, Object arg1, Object arg2) {
+		info(String.format(format, arg1, arg2));
+	}
+
+	@Override
+	public boolean isDebugEnabled() {
+		return getLog().isDebugEnabled();
+	}
+
+	@Override
+	public boolean isErrorEnabled() {
+		return getLog().isErrorEnabled();
+	}
+
+	@Override
+	public boolean isInfoEnabled() {
+		return getLog().isInfoEnabled();
+	}
+
+	@Override
+	public boolean isTraceEnabled() {
+		return false;
+	}
+
+	@Override
+	public boolean isWarnEnabled() {
+		return getLog().isWarnEnabled();
+	}
+
+	@Override
+	public void trace(String msg) {
+		// NOOP
+	}
+
+	@Override
+	public void trace(String msg, Object arg1) {
+		// NOOP
+	}
+
+	@Override
+	public void trace(String msg, Object[] arg1) {
+		// NOOP
+	}
+
+	@Override
+	public void trace(String msg, Throwable t) {
+		// NOOP
+	}
+
+	@Override
+	public void trace(String msg, Object arg1, Object arg2) {
+		// NOOP
+	}
+
+	@Override
+	public void warn(String msg) {
+		getLog().warn(msg);
+	}
+
+	@Override
+	public void warn(String format, Object arg1) {
+		warn(String.format(format, arg1));
+	}
+
+	@Override
+	public void warn(String format, Object[] arg1) {
+		warn(String.format(format, arg1));
+	}
+
+	@Override
+	public void warn(String msg, Throwable t) {
+		getLog().warn(msg, t);
+	}
+
+	@Override
+	public void warn(String format, Object arg1, Object arg2) {
+		warn(String.format(format, arg1, arg2));
+	}
+}

File duel-staticapps-maven-plugin/src/main/java/org/duelengine/duel/staticapps/maven/MavenLoggerAdapterFactory.java

View file
  • Ignore whitespace
+package org.duelengine.duel.staticapps.maven;
+
+import org.apache.maven.plugin.logging.Log;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.Logger;
+
+public class MavenLoggerAdapterFactory implements ILoggerFactory {
+
+	private static Log log;
+
+	static void setMavenLogger(Log log) {
+		MavenLoggerAdapterFactory.log = log;
+	}
+
+	@Override
+	public Logger getLogger(String name) {
+		return new MavenLoggerAdapter(name, log);
+	}
+}

File duel-staticapps-maven-plugin/src/main/java/org/duelengine/duel/staticapps/maven/SiteGeneratorMojo.java

View file
  • Ignore whitespace
+package org.duelengine.duel.staticapps.maven;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.duelengine.duel.staticapps.SiteBuilder;
+import org.duelengine.duel.staticapps.SiteConfig;
+
+//phase process-classes?
+/**
+ * Generates static app from DUEL-based WAR
+ *
+ * @goal generate
+ * @phase package
+ * @requiresDependencyResolution
+ */
+public class SiteGeneratorMojo extends AbstractMojo {
+
+	// http://maven.apache.org/ref/3.0.4/maven-model/maven.html#class_build
+
+	/**
+	 * The project currently being built.
+	 * 
+	 * @parameter default-value="${project}"
+	 * @required
+	 * @readonly
+	 */
+	private MavenProject project;
+
+	/**
+	 * The plugin descriptor
+	 * 
+	 * @parameter default-value="${descriptor}"
+	 */
+	private PluginDescriptor descriptor;
+
+	/**
+	 * Location of the configuration settings
+	 * 
+	 * @parameter default-value="${project.basedir}/staticapp.json"
+	 */
+	private String configPath;
+
+	@Override
+	public void setLog(Log log) {
+		super.setLog(log);
+
+		MavenLoggerAdapterFactory.setMavenLogger(log);
+	};
+
+	public void execute()
+		throws MojoExecutionException {
+
+		Log log = this.getLog();
+
+		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+		try {
+			// http://stackoverflow.com/q/871708/43217
+			log.info("adding build dependencies and target to classPath");
+			ClassRealm realm = descriptor.getClassRealm();
+			List<String> runtimeClasspathElements = project.getRuntimeClasspathElements();
+			List<URL> runtimeUrls = new ArrayList<URL>(runtimeClasspathElements.size());
+			for (String element : runtimeClasspathElements) {
+				try {
+					URL elementURL = new File(element).toURI().toURL();
+					runtimeUrls.add(elementURL);
+					if (realm != null) {
+						realm.addURL(elementURL);
+					}
+
+				} catch (MalformedURLException ex) {
+					log.error(ex);
+				}
+			}
+			classLoader = new URLClassLoader(runtimeUrls.toArray(new URL[runtimeUrls.size()]), classLoader);
+			Thread.currentThread().setContextClassLoader(classLoader);
+
+		} catch (DependencyResolutionRequiredException ex) {
+			log.error(ex);
+		}
+
+		try {
+			File configFile = new File(configPath);
+
+			if (!configFile.isFile()) {
+				throw new FileNotFoundException(configFile.getPath());
+			}
+
+			// read config
+			SiteConfig config = new ObjectMapper().reader(SiteConfig.class).readValue(configFile);
+
+			// ensure paths are relative from config
+			config
+				.sourceDir(new File(configFile.getParentFile(), config.sourceDir()).getPath())
+				.targetDir(new File(configFile.getParentFile(), config.targetDir()).getPath());
+
+			// build site defined by config
+			new SiteBuilder(classLoader).build(config);
+
+		} catch (IOException e) {
+			log.error(e);
+		}
+	}
+}

File duel-staticapps-maven-plugin/src/main/java/org/slf4j/impl/StaticLoggerBinder.java

View file
  • Ignore whitespace
+package org.slf4j.impl;
+
+import org.duelengine.duel.staticapps.maven.MavenLoggerAdapterFactory;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.LoggerFactory;
+import org.slf4j.spi.LoggerFactoryBinder;
+
+/**
+ * The binding of {@link LoggerFactory} class with an actual instance of
+ * {@link ILoggerFactory} is performed using information returned by this class.
+ */
+public class StaticLoggerBinder implements LoggerFactoryBinder {
+
+	/**
+	 * The unique instance of this class.
+	 * 
+	 */
+	private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
+	
+	/**
+	 * Return the singleton of this class.
+	 * 
+	 * @return the StaticLoggerBinder singleton
+	 */
+	public static final StaticLoggerBinder getSingleton() {
+		return SINGLETON;
+	}
+
+	/**
+	 * Declare the version of the SLF4J API this implementation is compiled
+	 * against. The value of this field is usually modified with each release.
+	 */
+	// to avoid constant folding by the compiler, this field must *not* be final
+	public static String REQUESTED_API_VERSION = "1.6";	 // !final
+	
+	private static final String loggerFactoryClassStr = MavenLoggerAdapterFactory.class.getName();
+
+	/**
+	 * The ILoggerFactory instance returned by the {@link #getLoggerFactory}
+	 * method should always be the same object
+	 */
+	private final ILoggerFactory loggerFactory;
+	
+	private StaticLoggerBinder() {
+		loggerFactory = new MavenLoggerAdapterFactory();
+	}
+	
+	public ILoggerFactory getLoggerFactory() {
+		return loggerFactory;
+	}
+	
+	public String getLoggerFactoryClassStr() {
+		return loggerFactoryClassStr;
+	}		
+}

File duel-staticapps-maven-plugin/src/main/java/org/slf4j/impl/StaticMDCBinder.java

View file
  • Ignore whitespace
+package org.slf4j.impl;
+
+import org.slf4j.helpers.NOPMDCAdapter;
+import org.slf4j.spi.MDCAdapter;
+
+/**
+ * This implementation is bound to {@link NOPMDCAdapter}.
+ */
+public class StaticMDCBinder {
+
+	/**
+	 * The unique instance of this class.
+	 */
+	public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
+
+	private StaticMDCBinder() {
+	}
+	
+	/**
+	 * Currently this method always returns an instance of 
+	 * {@link StaticMDCBinder}.
+	 */
+	public MDCAdapter getMDCA() {
+		 return new NOPMDCAdapter();
+	}
+	
+	public String	 getMDCAdapterClassStr() {
+		return NOPMDCAdapter.class.getName();
+	}
+}

File duel-staticapps-maven-plugin/src/main/java/org/slf4j/impl/StaticMarkerBinder.java

View file
  • Ignore whitespace
+package org.slf4j.impl;
+
+import org.slf4j.IMarkerFactory;
+import org.slf4j.MarkerFactory;
+import org.slf4j.helpers.BasicMarkerFactory;
+import org.slf4j.spi.MarkerFactoryBinder;
+
+/**
+ * 
+ * The binding of {@link MarkerFactory} class with an actual instance of 
+ * {@link IMarkerFactory} is performed using information returned by this class. 
+ */
+public class StaticMarkerBinder implements MarkerFactoryBinder {
+
+	/**
+	 * The unique instance of this class.
+	 */
+	public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder();
+	
+	final IMarkerFactory markerFactory = new BasicMarkerFactory();
+	
+	private StaticMarkerBinder() {
+	}
+	
+	/**
+	 * Currently this method always returns an instance of 
+	 * {@link BasicMarkerFactory}.
+	 */
+	public IMarkerFactory getMarkerFactory() {
+		return markerFactory;
+	}
+	
+	/**
+	 * Currently, this method returns the class name of
+	 * {@link BasicMarkerFactory}.
+	 */
+	public String getMarkerFactoryClassStr() {
+		return BasicMarkerFactory.class.getName();
+	}
+}

File duel-staticapps/src/main/java/org/duelengine/duel/staticapps/SiteBuilder.java

View file
  • Ignore whitespace
 
 	private static final Logger log = LoggerFactory.getLogger(SiteBuilder.class);
 	private static final int BUFFER_SIZE = 64*1024;//64K
+	private final ClassLoader classLoader;
 	private final byte[] buffer = new byte[BUFFER_SIZE];
 
+	public SiteBuilder() {
+		this(Thread.currentThread().getContextClassLoader());
+	}
+
+	public SiteBuilder(ClassLoader classLoader) {
+		this.classLoader = classLoader;
+	}
+
 	public void build(SiteConfig config)
 			throws FileNotFoundException {
 
 			String bundleName = config.cdnMap();
 			ResourceBundle cdnBundle =
 				(bundleName == null) || bundleName.isEmpty() ? null :
-				ResourceBundle.getBundle(bundleName, Locale.ROOT);
+				ResourceBundle.getBundle(bundleName, Locale.ROOT, classLoader);
 
 			bundleName = config.cdnLinksMap();
 			ResourceBundle cdnLinkBundle =
 				(bundleName == null) || bundleName.isEmpty() ? null :
-				ResourceBundle.getBundle(bundleName, Locale.ROOT);
+				ResourceBundle.getBundle(bundleName, Locale.ROOT, classLoader);
 
 			linkInterceptor = new StaticLinkInterceptor(config.cdnHost(), cdnBundle, cdnLinkBundle, config.isDevMode());
 
 	 * @return the view class
 	 * @throws ClassNotFoundException 
 	 */
-	private static Class<? extends DuelView> viewClass(String serverPrefix, String viewName)
+	private Class<? extends DuelView> viewClass(String serverPrefix, String viewName)
 			throws ClassNotFoundException {
 
 		if (serverPrefix != null && !serverPrefix.isEmpty()) {
 				viewName = serverPrefix + '.' + viewName;
 			}
 		}
-		return Class.forName(viewName).asSubclass(DuelView.class);
+		return Class.forName(viewName, true, classLoader).asSubclass(DuelView.class);
 	}
 }

File pom.xml

View file
  • Ignore whitespace
 		<module>duel-js</module>
 		<module>duel-runtime</module>
 		<module>duel-compiler</module>
+		<module>duel-maven-plugin</module>
 		<module>duel-staticapps</module>
-		<module>duel-maven-plugin</module>
+		<module>duel-staticapps-maven-plugin</module>
 	</modules>
 </project>