Skip to content

Commit

Permalink
Merge pull request #452 from robertpanzer/fix-450
Browse files Browse the repository at this point in the history
Fixes #450, Pass a RubyAttributesMapDecorator to Processors.
  • Loading branch information
robertpanzer committed Apr 19, 2016
2 parents 24872b9 + a2967ea commit 9d7d923
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package org.asciidoctor.extension.processorproxies;

import org.asciidoctor.ast.StructuralNode;
import org.asciidoctor.ast.NodeConverter;
import org.asciidoctor.ast.StructuralNode;
import org.asciidoctor.extension.BlockMacroProcessor;
import org.asciidoctor.internal.RubyAttributesMapDecorator;
import org.asciidoctor.internal.RubyHashMapDecorator;
import org.asciidoctor.internal.RubyHashUtil;
import org.asciidoctor.internal.RubyUtils;
Expand All @@ -19,7 +20,6 @@

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

public class BlockMacroProcessorProxy extends AbstractMacroProcessorProxy<BlockMacroProcessor> {

Expand Down Expand Up @@ -104,7 +104,7 @@ public IRubyObject process(ThreadContext context, IRubyObject parent, IRubyObjec
Object o = getProcessor().process(
(StructuralNode) NodeConverter.createASTNode(parent),
RubyUtils.rubyToJava(getRuntime(), target, String.class),
RubyUtils.rubyToJava(getRuntime(), attributes, Map.class));
new RubyAttributesMapDecorator((RubyHash) attributes));

return convertProcessorResult(o);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package org.asciidoctor.extension.processorproxies;

import org.asciidoctor.ast.StructuralNode;
import org.asciidoctor.ast.NodeConverter;
import org.asciidoctor.ast.StructuralNode;
import org.asciidoctor.extension.BlockProcessor;
import org.asciidoctor.extension.ReaderImpl;
import org.asciidoctor.internal.RubyAttributesMapDecorator;
import org.asciidoctor.internal.RubyHashMapDecorator;
import org.asciidoctor.internal.RubyHashUtil;
import org.asciidoctor.internal.RubyUtils;
Expand All @@ -20,7 +21,6 @@

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

public class BlockProcessorProxy extends AbstractProcessorProxy<BlockProcessor> {

Expand Down Expand Up @@ -117,7 +117,7 @@ public IRubyObject process(ThreadContext context, IRubyObject parent, IRubyObjec
Object o = getProcessor().process(
(StructuralNode) NodeConverter.createASTNode(parent),
new ReaderImpl(reader),
RubyUtils.rubyToJava(getRuntime(), attributes, Map.class));
new RubyAttributesMapDecorator((RubyHash) attributes));

return convertProcessorResult(o);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.asciidoctor.extension.IncludeProcessor;
import org.asciidoctor.extension.PreprocessorReader;
import org.asciidoctor.extension.PreprocessorReaderImpl;
import org.asciidoctor.internal.RubyAttributesMapDecorator;
import org.asciidoctor.internal.RubyHashMapDecorator;
import org.asciidoctor.internal.RubyHashUtil;
import org.asciidoctor.internal.RubyUtils;
Expand Down Expand Up @@ -108,7 +109,7 @@ public IRubyObject process(ThreadContext context, IRubyObject[] args) {
Document document = (Document) NodeConverter.createASTNode(args[0]);
PreprocessorReader reader = new PreprocessorReaderImpl(args[1]);
String target = RubyUtils.rubyToJava(getRuntime(), args[2], String.class);
Map<String, Object> attributes = RubyUtils.rubyToJava(getRuntime(), args[3], Map.class);
Map<String, Object> attributes = new RubyAttributesMapDecorator((RubyHash) args[3]);
getProcessor().process(document, reader, target, attributes);
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package org.asciidoctor.extension.processorproxies;

import org.asciidoctor.ast.NodeConverter;
import org.asciidoctor.ast.StructuralNode;
import org.asciidoctor.extension.InlineMacroProcessor;
import org.asciidoctor.internal.RubyAttributesMapDecorator;
import org.asciidoctor.internal.RubyHashMapDecorator;
import org.asciidoctor.internal.RubyHashUtil;
import org.asciidoctor.internal.RubyUtils;
Expand All @@ -18,7 +20,6 @@
import org.jruby.runtime.builtin.IRubyObject;

import java.lang.reflect.InvocationTargetException;
import java.util.Map;

public class InlineMacroProcessorProxy extends AbstractMacroProcessorProxy<InlineMacroProcessor> {

Expand Down Expand Up @@ -115,7 +116,7 @@ public IRubyObject process(ThreadContext context, IRubyObject parent, IRubyObjec
Object o = getProcessor().process(
NodeConverter.createASTNode(parent),
RubyUtils.rubyToJava(getRuntime(), target, String.class),
RubyUtils.rubyToJava(getRuntime(), attributes, Map.class));
new RubyAttributesMapDecorator((RubyHash) attributes));
return convertProcessorResult(o);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,12 @@ private IRubyObject convertJavaValue(Object value) {
public String toString() {
return createJavaMap().toString();
}

/**
* Invoked by JRuby when the map should be copied.
* @return
*/
public Object dup() {
return new RubyHashMapDecorator((RubyHash) rubyHash.dup());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private Map<String, Object> createJavaMap() {
Map<String, Object> copy = new HashMap<String, Object>();
Set<Entry<Object, Object>> rubyEntrySet = rubyHash.entrySet();
for (Map.Entry<Object, Object> o: rubyEntrySet) {
String key;
String key = null;
Object value;
Object rubyKey = o.getKey();
Object rubyValue = o.getValue();
Expand All @@ -114,11 +114,15 @@ private Map<String, Object> createJavaMap() {
key = ((RubyString) rubyKey).asJavaString();
} else if (rubyKey instanceof String) {
key = (String) rubyKey;
} else if (rubyKey instanceof Long) {
// Skip it silently, it is a positional attribute
} else {
throw new IllegalStateException("Did not expect key " + rubyKey + " of type " + rubyKey.getClass());
}
value = convertRubyValue(rubyValue);
copy.put(key, value);
if (key != null) {
value = convertRubyValue(rubyValue);
copy.put(key, value);
}
}
return copy;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.asciidoctor.extension

import org.asciidoctor.ast.StructuralNode

@Contexts([Contexts.CONTEXT_PARAGRAPH])
@Name('checkattributes')
class AttributeCheckingBlockProcessor extends BlockProcessor {


@Override
Object process(StructuralNode parent, Reader reader, Map<String, Object> attributes) {
attributes.keySet().each { assert it in String }
parent
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.asciidoctor.extension

import org.asciidoctor.Asciidoctor
import org.asciidoctor.OptionsBuilder
import org.asciidoctor.SafeMode
import org.jboss.arquillian.spock.ArquillianSputnik
import org.jboss.arquillian.test.api.ArquillianResource
import org.junit.runner.RunWith
import spock.lang.Issue
import spock.lang.Specification

@Issue('https://github.com/asciidoctor/asciidoctorj/issues/450')
@RunWith(ArquillianSputnik)
class WhenAJavaExtensionChecksAttributes extends Specification {


private static final String DOCUMENT = '''= Test document
[checkattributes,avalue]
Check me
'''

@ArquillianResource
private Asciidoctor asciidoctor

def "a BlockProcessor should only get String attribute keys"() {
when:
asciidoctor.javaExtensionRegistry().block(AttributeCheckingBlockProcessor)
asciidoctor.convert(DOCUMENT, OptionsBuilder.options().headerFooter(true).safe(SafeMode.SERVER))

then:
noExceptionThrown()
}
}

0 comments on commit 9d7d923

Please sign in to comment.