Update to latest Asciidoctor version
We will temporarily remove PDF support until the plugin supports it.
|
@ -3,13 +3,13 @@ import groovy.text.SimpleTemplateEngine
|
|||
buildscript {
|
||||
repositories {
|
||||
maven { url "http://repo.springsource.org/plugins-release" }
|
||||
maven { url "http://jcenter.bintray.com"}
|
||||
}
|
||||
dependencies {
|
||||
classpath("org.springframework.build.gradle:propdeps-plugin:0.0.3")
|
||||
classpath("org.springframework.build.gradle:bundlor-plugin:0.1.2")
|
||||
classpath("org.gradle.api.plugins:gradle-tomcat-plugin:0.9.8")
|
||||
classpath('me.champeau.gradle:gradle-javadoc-hotfix-plugin:0.1')
|
||||
classpath('org.asciidoctor:asciidoctor-gradle-plugin:0.7.0')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,22 +31,6 @@ dependencies {
|
|||
'net.sourceforge.saxon:saxon:9.1.0.8'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile('org.asciidoctor:asciidoctor-java-integration:0.1.3') {
|
||||
exclude group: 'rubygems', module :'haml'
|
||||
exclude group: 'rubygems', module :'asciidoctor'
|
||||
exclude group: 'rubygems', module :'coderay'
|
||||
exclude group: 'rubygems', module :'tilt'
|
||||
exclude group: 'rubygems', module :'erubis'
|
||||
exclude group: 'rubygems', module :'slim'
|
||||
}
|
||||
compile 'net.alchim31:livereload-jvm:0.1.0'
|
||||
compile 'org.apache.avalon.framework:avalon-framework-api:4.3.1'
|
||||
compile 'org.apache.avalon.framework:avalon-framework-impl:4.3.1'
|
||||
compile 'org.apache.xmlgraphics:fop:1.1'
|
||||
runtime 'net.sf.xslthl:xslthl:2.1.0'
|
||||
}
|
||||
|
||||
task ide(type: Copy) {
|
||||
from configurations.runtime
|
||||
into 'ide'
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.asciidoctor.gradle
|
||||
|
||||
/**
|
||||
* Supported backends.
|
||||
*
|
||||
* @author Benjamin Muschko
|
||||
*/
|
||||
enum AsciidoctorBackend {
|
||||
HTML5('html5'), DOCBOOK('docbook'), PDF('pdf')
|
||||
|
||||
private final static Map<String, AsciidoctorBackend> ALL_BACKENDS
|
||||
private final String id
|
||||
|
||||
static {
|
||||
ALL_BACKENDS = values().collectEntries{ [it.id, it] }.asImmutable()
|
||||
}
|
||||
|
||||
private AsciidoctorBackend(String id) {
|
||||
this.id = id
|
||||
}
|
||||
|
||||
String getId() {
|
||||
id
|
||||
}
|
||||
|
||||
static boolean isSupported(String name) {
|
||||
ALL_BACKENDS.containsKey(name)
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.asciidoctor.gradle
|
||||
|
||||
import groovy.lang.Closure;
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
|
||||
/**
|
||||
* @author Noam Tenne
|
||||
* @author Andres Almiray
|
||||
*/
|
||||
class AsciidoctorPlugin implements Plugin<Project> {
|
||||
void apply(Project project) {
|
||||
project.task('asciidoctor', type: AsciidoctorTask, group: 'Documentation')
|
||||
}
|
||||
}
|
|
@ -1,207 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.asciidoctor.gradle
|
||||
|
||||
import org.asciidoctor.gradle.*
|
||||
|
||||
|
||||
import org.apache.commons.io.IOUtils
|
||||
import org.asciidoctor.Asciidoctor
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.InvalidUserDataException
|
||||
import org.gradle.api.file.*
|
||||
import org.gradle.api.tasks.*
|
||||
|
||||
import javax.xml.transform.*
|
||||
import javax.xml.transform.stream.*
|
||||
import javax.xml.transform.sax.*
|
||||
import org.apache.fop.apps.FopFactory
|
||||
import org.apache.fop.apps.Fop
|
||||
import org.apache.fop.apps.MimeConstants
|
||||
|
||||
|
||||
class AsciidoctorTask extends DefaultTask {
|
||||
@InputFiles FileCollection sourceDocuments
|
||||
@Input Map options = [:]
|
||||
|
||||
@Optional @OutputDirectory File outputDir
|
||||
@Optional @Input List<String> backends
|
||||
|
||||
AsciidoctorTask() {
|
||||
sourceDocuments = project.fileTree("src/asciidoctor/").include("*.adoc")
|
||||
outputDir = project.file("${project.buildDir}/asciidoctor")
|
||||
backends = [AsciidoctorBackend.HTML5.id]
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
void render() {
|
||||
|
||||
Asciidoctor asciidoctor = Asciidoctor.Factory.create()
|
||||
for(File sourceDocument : sourceDocuments) {
|
||||
render(asciidoctor, sourceDocument)
|
||||
}
|
||||
}
|
||||
|
||||
void render(Asciidoctor asciidoctor, File sourceDocument) {
|
||||
for(backend in backends) {
|
||||
boolean isPdf = backend == AsciidoctorBackend.PDF.id
|
||||
String asciidoctorBackend = isPdf ? AsciidoctorBackend.DOCBOOK.id : backend
|
||||
|
||||
File distDir = new File("${outputDir}/dist/$backend")
|
||||
File workingDir = new File("${outputDir}/work/$backend")
|
||||
|
||||
[workingDir,distDir]*.mkdirs()
|
||||
|
||||
try {
|
||||
asciidoctor.renderFile(sourceDocument, mergedOptions(options, isPdf ? workingDir : distDir, asciidoctorBackend))
|
||||
|
||||
if(isPdf) {
|
||||
generatePdf(sourceDocument, workingDir,distDir)
|
||||
} else {
|
||||
project.copy {
|
||||
from "${sourceDocument.parent}/images"
|
||||
into "${distDir}/images/"
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new GradleException("Error running Asciidoctor on single source $sourceDocument for backend $asciidoctorBackend", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generatePdf(File sourceDocument, File workingDir, File distDir) {
|
||||
String docbookXmlUrl = 'http://maven-us.nuxeo.org/nexus/content/repositories/public/docbook/docbook-xml/4.5/docbook-xml-4.5.jar'
|
||||
String docbookXslUrl = 'http://downloads.sourceforge.net/project/docbook/docbook-xsl-ns/1.78.1/docbook-xsl-ns-1.78.1.zip'
|
||||
|
||||
File docbookXmlFile = downloadFile(docbookXmlUrl)
|
||||
File docbookXslFile = downloadFile(docbookXslUrl)
|
||||
|
||||
project.copy {
|
||||
from "src/asciidoctor/images"
|
||||
into "${workingDir}/images/"
|
||||
}
|
||||
|
||||
project.copy {
|
||||
from project.zipTree(docbookXmlFile)
|
||||
into "$workingDir/docbook"
|
||||
}
|
||||
|
||||
project.copy {
|
||||
from(project.zipTree(docbookXslFile)) {
|
||||
eachFile { details ->
|
||||
details.path = details.path.substring(details.relativePath.segments[0].length())
|
||||
}
|
||||
}
|
||||
into "$workingDir/docbook/"
|
||||
}
|
||||
|
||||
unzipDockbookXsl(workingDir)
|
||||
|
||||
def outputUri = workingDir.toURI().toASCIIString()
|
||||
|
||||
Vector params = new Vector()
|
||||
params.add("highlight.xslthl.config")
|
||||
params.add(outputUri + "docbook-xsl/xslthl-config.xml")
|
||||
params.add("admon.graphics.path")
|
||||
params.add(outputUri + "docbook/images/")
|
||||
params.add("callout.graphics.path")
|
||||
params.add(outputUri + "docbook/images/callouts/")
|
||||
params.add("img.src.path")
|
||||
params.add(outputUri)
|
||||
params.add("fop-output-format")
|
||||
params.add("application/pdf")
|
||||
params.add("fop-version")
|
||||
params.add("1.1")
|
||||
|
||||
File outputFile = new File("${distDir}/", sourceDocument.name.replaceAll("\\..*", ".pdf"))
|
||||
File docbookFile = new File("$workingDir/",sourceDocument.name.replaceAll("\\..*", ".xml"))
|
||||
File xsltFile = new File("${workingDir}/docbook-xsl/fo-pdf.xsl")
|
||||
|
||||
InputHandler handler = new InputHandler(docbookFile, xsltFile, params)
|
||||
|
||||
FopFactory fopFactory = FopFactory.newInstance(); // Reuse the FopFactory if possible!
|
||||
fopFactory.setUserConfig(new File("${workingDir}/docbook-xsl/fop-config.xml"))
|
||||
// do the following for each new rendering run
|
||||
def foUserAgent = fopFactory.newFOUserAgent();
|
||||
|
||||
handler.createCatalogResolver(foUserAgent)
|
||||
|
||||
def out = new java.io.BufferedOutputStream(
|
||||
new java.io.FileOutputStream(outputFile));
|
||||
|
||||
foUserAgent.setOutputFile(outputFile);
|
||||
|
||||
try {
|
||||
handler.renderTo(foUserAgent, MimeConstants.MIME_PDF, out)
|
||||
} finally {
|
||||
IOUtils.closeQuietly(out)
|
||||
}
|
||||
}
|
||||
|
||||
private void unzipDockbookXsl(def installDir) {
|
||||
def docbookXslResourceName = 'docbook-xsl.zip'
|
||||
def docbookXslInputStream = this.class.classLoader.getResourceAsStream(docbookXslResourceName)
|
||||
if (docbookXslInputStream == null) {
|
||||
throw new GradleException("could not find ${docbookXslResourceName} on the classpath");
|
||||
}
|
||||
// the file is a jar:file - write it to disk first
|
||||
File docbookXslOutputFile = new File("${installDir}/downloads/${docbookXslResourceName}")
|
||||
docbookXslOutputFile.parentFile.mkdirs()
|
||||
IOUtils.copy(docbookXslInputStream, new FileOutputStream(docbookXslOutputFile))
|
||||
project.copy {
|
||||
from project.zipTree(docbookXslOutputFile)
|
||||
into "${installDir}/"
|
||||
}
|
||||
}
|
||||
|
||||
private File downloadFile(String url) {
|
||||
def home = System.getProperty("user.home")
|
||||
File destinationFile = new File("${home}/.fopdf/downloads", url.split("/")[-1])
|
||||
destinationFile.parentFile.mkdirs()
|
||||
|
||||
if(!destinationFile.exists()) {
|
||||
logger.info("Downloading " + url + " to "+ destinationFile + "...")
|
||||
destinationFile.bytes = new URL(url).bytes
|
||||
}
|
||||
destinationFile
|
||||
}
|
||||
|
||||
private static Map<String, Object> mergedOptions(Map options, File outputDir, String backend) {
|
||||
Map<String, Object> mergedOptions = [:]
|
||||
mergedOptions.putAll(options)
|
||||
mergedOptions.in_place = false
|
||||
mergedOptions.safe = 0i
|
||||
mergedOptions.to_dir = outputDir.absolutePath
|
||||
Map attributes = mergedOptions.get('attributes', [:])
|
||||
attributes.backend = backend
|
||||
|
||||
// Issue #14 force GString -> String as jruby will fail
|
||||
// to find an exact match when invoking Asciidoctor
|
||||
for (entry in mergedOptions) {
|
||||
if (entry.value instanceof CharSequence) {
|
||||
mergedOptions[entry.key] = entry.value.toString()
|
||||
}
|
||||
}
|
||||
for (entry in attributes) {
|
||||
if (entry.value instanceof CharSequence) {
|
||||
attributes[entry.key] = entry.value.toString()
|
||||
}
|
||||
}
|
||||
mergedOptions
|
||||
}
|
||||
}
|
|
@ -1,336 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
package org.asciidoctor.gradle;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import javax.xml.transform.ErrorListener;
|
||||
import javax.xml.transform.Result;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.URIResolver;
|
||||
import javax.xml.transform.sax.SAXResult;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.apache.fop.ResourceEventProducer;
|
||||
import org.apache.fop.apps.FOPException;
|
||||
import org.apache.fop.apps.FOUserAgent;
|
||||
import org.apache.fop.apps.Fop;
|
||||
import org.apache.fop.apps.FopFactory;
|
||||
import org.apache.fop.render.awt.viewer.Renderable;
|
||||
|
||||
/**
|
||||
* Class for handling files input from command line
|
||||
* either with XML and XSLT files (and optionally xsl
|
||||
* parameters) or FO File input alone.
|
||||
*/
|
||||
public class InputHandler implements ErrorListener, Renderable {
|
||||
|
||||
/** original source file */
|
||||
protected File sourcefile;
|
||||
private File stylesheet; // for XML/XSLT usage
|
||||
private Vector xsltParams; // for XML/XSLT usage
|
||||
private EntityResolver entityResolver = null;
|
||||
private URIResolver uriResolver = null;
|
||||
|
||||
/** the logger */
|
||||
protected Log log = LogFactory.getLog(InputHandler.class);
|
||||
|
||||
/**
|
||||
* Constructor for XML->XSLT->FO input
|
||||
*
|
||||
* @param xmlfile XML file
|
||||
* @param xsltfile XSLT file
|
||||
* @param params Vector of command-line parameters (name, value,
|
||||
* name, value, ...) for XSL stylesheet, null if none
|
||||
*/
|
||||
public InputHandler(File xmlfile, File xsltfile, Vector params) {
|
||||
if(!xsltfile.exists()) {
|
||||
throw new RuntimeException("Couldn't find "+ xsltfile);
|
||||
}
|
||||
sourcefile = xmlfile;
|
||||
stylesheet = xsltfile;
|
||||
xsltParams = params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for FO input
|
||||
* @param fofile the file to read the FO document.
|
||||
*/
|
||||
public InputHandler(File fofile) {
|
||||
sourcefile = fofile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a document, given an initialized Fop object
|
||||
* @param userAgent the user agent
|
||||
* @param outputFormat the output format to generate (MIME type, see MimeConstants)
|
||||
* @param out the output stream to write the generated output to (may be null if not applicable)
|
||||
* @throws FOPException in case of an error during processing
|
||||
*/
|
||||
public void renderTo(FOUserAgent userAgent, String outputFormat, OutputStream out)
|
||||
throws FOPException {
|
||||
|
||||
FopFactory factory = userAgent.getFactory();
|
||||
Fop fop;
|
||||
if (out != null) {
|
||||
fop = factory.newFop(outputFormat, userAgent, out);
|
||||
} else {
|
||||
fop = factory.newFop(outputFormat, userAgent);
|
||||
}
|
||||
|
||||
// if base URL was not explicitly set in FOUserAgent, obtain here
|
||||
if (fop.getUserAgent().getBaseURL() == null && sourcefile != null) {
|
||||
String baseURL = null;
|
||||
|
||||
try {
|
||||
baseURL = new File(sourcefile.getAbsolutePath())
|
||||
.getParentFile().toURI().toURL().toExternalForm();
|
||||
} catch (Exception e) {
|
||||
baseURL = "";
|
||||
}
|
||||
fop.getUserAgent().setBaseURL(baseURL);
|
||||
}
|
||||
|
||||
// Resulting SAX events (the generated FO) must be piped through to FOP
|
||||
Result res = new SAXResult(fop.getDefaultHandler());
|
||||
|
||||
transformTo(res);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void renderTo(FOUserAgent userAgent, String outputFormat) throws FOPException {
|
||||
renderTo(userAgent, outputFormat, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* In contrast to render(Fop) this method only performs the XSLT stage and saves the
|
||||
* intermediate XSL-FO file to the output file.
|
||||
* @param out OutputStream to write the transformation result to.
|
||||
* @throws FOPException in case of an error during processing
|
||||
*/
|
||||
public void transformTo(OutputStream out) throws FOPException {
|
||||
Result res = new StreamResult(out);
|
||||
transformTo(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Source for the main input file. Processes XInclude if
|
||||
* available in the XML parser.
|
||||
*
|
||||
* @return the Source for the main input file
|
||||
*/
|
||||
protected Source createMainSource() {
|
||||
Source source;
|
||||
InputStream in;
|
||||
String uri;
|
||||
if (this.sourcefile != null) {
|
||||
try {
|
||||
in = new java.io.FileInputStream(this.sourcefile);
|
||||
uri = this.sourcefile.toURI().toASCIIString();
|
||||
} catch (FileNotFoundException e) {
|
||||
//handled elsewhere
|
||||
return new StreamSource(this.sourcefile);
|
||||
}
|
||||
} else {
|
||||
in = System.in;
|
||||
uri = null;
|
||||
}
|
||||
try {
|
||||
InputSource is = new InputSource(in);
|
||||
is.setSystemId(uri);
|
||||
XMLReader xr = getXMLReader();
|
||||
if (entityResolver != null) {
|
||||
xr.setEntityResolver(entityResolver);
|
||||
}
|
||||
source = new SAXSource(xr, is);
|
||||
} catch (SAXException e) {
|
||||
if (this.sourcefile != null) {
|
||||
source = new StreamSource(this.sourcefile);
|
||||
} else {
|
||||
source = new StreamSource(in, uri);
|
||||
}
|
||||
} catch (ParserConfigurationException e) {
|
||||
if (this.sourcefile != null) {
|
||||
source = new StreamSource(this.sourcefile);
|
||||
} else {
|
||||
source = new StreamSource(in, uri);
|
||||
}
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a catalog resolver and uses it for XML parsing and XSLT URI resolution.
|
||||
* Tries the Apache Commons Resolver, and if unsuccessful,
|
||||
* tries the same built into Java 6.
|
||||
* @param userAgent the user agent instance
|
||||
*/
|
||||
public void createCatalogResolver(FOUserAgent userAgent) {
|
||||
String[] classNames = new String[] {
|
||||
"org.apache.xml.resolver.tools.CatalogResolver",
|
||||
"com.sun.org.apache.xml.internal.resolver.tools.CatalogResolver"};
|
||||
ResourceEventProducer eventProducer
|
||||
= ResourceEventProducer.Provider.get(userAgent.getEventBroadcaster());
|
||||
Class resolverClass = null;
|
||||
for (int i = 0; i < classNames.length && resolverClass == null; ++i) {
|
||||
try {
|
||||
resolverClass = Class.forName(classNames[i]);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// No worries
|
||||
}
|
||||
}
|
||||
if (resolverClass == null) {
|
||||
eventProducer.catalogResolverNotFound(this);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
entityResolver = (EntityResolver) resolverClass.newInstance();
|
||||
uriResolver = (URIResolver) resolverClass.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
log.error("Error creating the catalog resolver: " + e.getMessage());
|
||||
eventProducer.catalogResolverNotCreated(this, e.getMessage());
|
||||
} catch (IllegalAccessException e) {
|
||||
log.error("Error creating the catalog resolver: " + e.getMessage());
|
||||
eventProducer.catalogResolverNotCreated(this, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Source for the selected stylesheet.
|
||||
*
|
||||
* @return the Source for the selected stylesheet or null if there's no stylesheet
|
||||
*/
|
||||
protected Source createXSLTSource() {
|
||||
Source xslt = null;
|
||||
if (this.stylesheet != null) {
|
||||
if (entityResolver != null) {
|
||||
try {
|
||||
InputSource is = new InputSource(this.stylesheet.getPath());
|
||||
XMLReader xr = getXMLReader();
|
||||
xr.setEntityResolver(entityResolver);
|
||||
xslt = new SAXSource(xr, is);
|
||||
} catch (SAXException e) {
|
||||
// return StreamSource
|
||||
} catch (ParserConfigurationException e) {
|
||||
// return StreamSource
|
||||
}
|
||||
}
|
||||
if (xslt == null) {
|
||||
xslt = new StreamSource(this.stylesheet);
|
||||
}
|
||||
}
|
||||
return xslt;
|
||||
}
|
||||
|
||||
private XMLReader getXMLReader() throws ParserConfigurationException, SAXException {
|
||||
SAXParserFactory spf = SAXParserFactory.newInstance();
|
||||
spf.setFeature("http://xml.org/sax/features/namespaces", true);
|
||||
spf.setFeature("http://apache.org/xml/features/xinclude", true);
|
||||
XMLReader xr = spf.newSAXParser().getXMLReader();
|
||||
return xr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the input document to the input format expected by FOP using XSLT.
|
||||
* @param result the Result object where the result of the XSL transformation is sent to
|
||||
* @throws FOPException in case of an error during processing
|
||||
*/
|
||||
protected void transformTo(Result result) throws FOPException {
|
||||
try {
|
||||
// Setup XSLT
|
||||
System.setProperty("javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl");
|
||||
TransformerFactory factory = TransformerFactory.newInstance();
|
||||
if (uriResolver != null) {
|
||||
factory.setURIResolver(uriResolver);
|
||||
}
|
||||
factory.setErrorListener(this);
|
||||
Transformer transformer;
|
||||
|
||||
Source xsltSource = createXSLTSource();
|
||||
if (xsltSource == null) { // FO Input
|
||||
transformer = factory.newTransformer();
|
||||
} else { // XML/XSLT input
|
||||
transformer = factory.newTransformer(xsltSource);
|
||||
|
||||
// Set the value of parameters, if any, defined for stylesheet
|
||||
if (xsltParams != null) {
|
||||
for (int i = 0; i < xsltParams.size(); i += 2) {
|
||||
transformer.setParameter((String) xsltParams.elementAt(i),
|
||||
(String) xsltParams.elementAt(i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
transformer.setErrorListener(this);
|
||||
|
||||
// Create a SAXSource from the input Source file
|
||||
Source src = createMainSource();
|
||||
|
||||
// Start XSLT transformation and FOP processing
|
||||
transformer.transform(src, result);
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new FOPException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Implementation of the ErrorListener interface ---
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void warning(TransformerException exc) {
|
||||
log.warn(exc.getLocalizedMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void error(TransformerException exc) {
|
||||
log.error(exc.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void fatalError(TransformerException exc)
|
||||
throws TransformerException {
|
||||
throw exc;
|
||||
}
|
||||
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
implementation-class=org.asciidoctor.gradle.AsciidoctorPlugin
|
|
@ -12,7 +12,6 @@ project('manual') {
|
|||
ext.expandPlaceholders = ""
|
||||
|
||||
asciidoctor {
|
||||
backends = ["html5", "pdf"]
|
||||
options = [
|
||||
eruby: 'erubis',
|
||||
attributes: [
|
||||
|
@ -34,10 +33,8 @@ project('manual') {
|
|||
|
||||
ext.spec = copySpec {
|
||||
into ('reference/htmlsingle') {
|
||||
from("${asciidoctor.outputDir}/dist/html5")
|
||||
}
|
||||
into ('reference/pdf') {
|
||||
from("${asciidoctor.outputDir}/dist/pdf")
|
||||
from(asciidoctor.outputDir)
|
||||
exclude 'build', 'Guardfile'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import org.asciidoctor.gradle.*
|
|||
|
||||
file("src/asciidoc").eachFileMatch(~/.*\.asc/) { file->
|
||||
task "asciidoctor-${file.name}"(type: AsciidoctorTask) {
|
||||
sourceDocument = file
|
||||
sourceDocumentName = file
|
||||
options = [
|
||||
eruby: 'erubis',
|
||||
eruby: 'erubis',
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
:author: Rob Winch
|
||||
:starter-appname: hellomvc-jc
|
||||
:completed-appname: form-jc
|
||||
:verify-starter-app-include: form-includes/verify-app.asc
|
||||
:include-dir: src/asciidoc/_hello-includes
|
||||
:verify-starter-app-include: ../_form-includes/verify-app.asc
|
||||
|
||||
This guide builds off of link:hellomvc.html[Hello Spring MVC Security Java Config] to explain how to configure and use a custom login form with Spring Security Java Configuration.
|
||||
|
||||
include::hello-includes/setting-up-the-sample.asc[]
|
||||
include::{include-dir}/setting-up-the-sample.asc[]
|
||||
|
||||
= Overriding the default configure(HttpSecurity) method
|
||||
|
||||
|
@ -201,13 +202,12 @@ Our existing configuration means that all we need to do is create a *login.jspx*
|
|||
|
||||
<1> The URL we submit our username and password to is the same URL as our login form (i.e. */login*), but a *POST* instead of a *GET*.
|
||||
<2> When authentication fails, the browser is redirected to */login?error* so we can display an error message by detecting if the parameter *error* is non-null.
|
||||
|
||||
IMPORTANT: Do not display details about why authentication failed. For example, we do not want to display that the user does not exist as this will tell an attacker that they should try a different username.
|
||||
|
||||
<3> When we are successfully loged out, the browser is redirected to */login?logout* so we can display an logout success message by detecting if the parameter *logout* is non-null.
|
||||
<4> The username should be present on the HTTP parameter username
|
||||
<5> The password should be present on the HTTP parameter password
|
||||
|
||||
IMPORTANT: Do not display details about why authentication failed. For example, we do not want to display that the user does not exist as this will tell an attacker that they should try a different username.
|
||||
|
||||
TIP: We use Spring Web MVC's <form:form> tag to automatically add the CSRF token to our form. We could also manually add the CSRF token using `<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>`.
|
||||
|
||||
Start up the server and try visiting http://localhost:8080/sample/ to see the updates to our configuration. We now see our login page, but it does not look very pretty. The issue is that we have not granted access to the css files.
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
:author: Rob Winch
|
||||
:starter-appname: insecuremvc
|
||||
:completed-appname: hellomvc-jc
|
||||
:verify-starter-app-include: hello-includes/verify-insecuremvc-app.asc
|
||||
:include-dir: src/asciidoc/_hello-includes
|
||||
:verify-starter-app-include: verify-insecuremvc-app.asc
|
||||
|
||||
This guide provides instructions on how to add Spring Security to an existing Spring MVC application without the use of XML.
|
||||
|
||||
include::hello-includes/setting-up-the-sample.asc[]
|
||||
include::{include-dir}/setting-up-the-sample.asc[]
|
||||
|
||||
include::hello-includes/secure-the-application.asc[]
|
||||
include::{include-dir}/secure-the-application.asc[]
|
||||
|
||||
=== Registering Spring Security with the war
|
||||
|
||||
|
@ -76,7 +77,7 @@ The `@ComponentScan` is loading all configuration in the org.springframework.sec
|
|||
|
||||
NOTE: Had <<security-config-java,`SecurityConfig`>> not been loaded, we could have used an `@Import(SecurityConfig)` above the class definition of <<root-configuration-java,`RootConfiguration`>> or added <<security-config-java,`SecurityConfig`>> as one of the results for `getRootConfigClasses()`.
|
||||
|
||||
include::hello-includes/exploring-the-secured-application.asc[]
|
||||
include::{include-dir}/exploring-the-secured-application.asc[]
|
||||
|
||||
==== Displaying the user name
|
||||
|
||||
|
@ -138,7 +139,7 @@ In order to help protect against http://en.wikipedia.org/wiki/Cross-site_request
|
|||
|
||||
Refresh the page at http://localhost:8080/sample/ and you will see the log out button. Click the button and see that the application logs you out successfully.
|
||||
|
||||
include::hello-includes/basic-authentication.asc[]
|
||||
include::{include-dir}/basic-authentication.asc[]
|
||||
|
||||
== Conclusion
|
||||
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
:author: Rob Winch
|
||||
:starter-appname: insecure
|
||||
:completed-appname: helloworld-jc
|
||||
:verify-starter-app-include: hello-includes/verify-insecure-app.asc
|
||||
:include-dir: src/asciidoc/_hello-includes
|
||||
:verify-starter-app-include: verify-insecure-app.asc
|
||||
|
||||
This guide provides instructions on how to add Spring Security to an existing application without the use of XML.
|
||||
|
||||
include::hello-includes/setting-up-the-sample.asc[]
|
||||
include::{include-dir}/setting-up-the-sample.asc[]
|
||||
|
||||
include::hello-includes/secure-the-application.asc[]
|
||||
include::{include-dir}/secure-the-application.asc[]
|
||||
|
||||
=== Registering Spring Security with the war
|
||||
|
||||
|
@ -44,7 +45,7 @@ The `SecurityWebApplicationInitializer` will do the following things:
|
|||
|
||||
NOTE: Since we were not already using Spring, this is a simple way to add our <<security-config-java,`SecurityConfig`>>. If we were already using Spring, then we should add our <<security-config-java,`SecurityConfig`>> with the reset of our Spring configuration (i.e. a subclass of AbstractContextLoaderInitializer or AbstractDispatcherServletInitializer) and use the default constructor instead.
|
||||
|
||||
include::hello-includes/exploring-the-secured-application.asc[]
|
||||
include::{include-dir}/exploring-the-secured-application.asc[]
|
||||
|
||||
==== Displaying the user name
|
||||
|
||||
|
@ -96,7 +97,7 @@ In order to help protect against http://en.wikipedia.org/wiki/Cross-site_request
|
|||
|
||||
Refresh the page at http://localhost:8080/sample/ and you will see the log out button. Click the logout button and see that the application logs you out successfully.
|
||||
|
||||
include::hello-includes/basic-authentication.asc[]
|
||||
include::{include-dir}/basic-authentication.asc[]
|
||||
|
||||
== Conclusion
|
||||
|
||||
|
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |