Skip to content

Commit

Permalink
Merge pull request #8 from trevershick/6_json_output
Browse files Browse the repository at this point in the history
Refactor formatters and parsers
  • Loading branch information
trevershick committed Nov 12, 2016
2 parents 5db22f0 + 262080c commit 04d4eff
Show file tree
Hide file tree
Showing 32 changed files with 1,555 additions and 287 deletions.
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,21 @@ Then in your Java code

```java

final Whitelist whitelist = GsonWhitelistConfiguration.fromJson(json).whitelist();
// you can simply instantiate the parser
final Whitelist whitelist = new GsonParser().parse(json).whitelist();

// or you can get a parser by 'type', (either gson or jowli)
final Whitelist whitelist = WhitelistConfigurationParserFactory.newParser("gson").parse(json).whitelist();

// or you can append to an existing whitelist
final Whitelist whitelist = new GsonParser().parse(json).apply(Whitelist.basic());

// you can construct a new config and serialize it out too!
WhitelistConfiguration wlc = new BasicWhitelistConfiguration().enforceAttribute("a","rel","nofollow");

final String jowli = new JowliMLFormatter().format(wlc).toString(); //jowliml
final String json = new GsonFormatter().format(wlc).toString(); //json


```

Expand Down
195 changes: 130 additions & 65 deletions core/src/main/java/io/shick/jsoup/BasicWhitelistConfiguration.java
Original file line number Diff line number Diff line change
@@ -1,124 +1,154 @@
package io.shick.jsoup;

import static io.shick.jsoup.Func.hashMap;
import static io.shick.jsoup.Func.list;
import static io.shick.jsoup.util.Func.hashMap;
import static io.shick.jsoup.util.Func.list;
import static java.util.Objects.requireNonNull;

import io.shick.jsoup.util.Func;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

import org.jsoup.safety.Whitelist;

abstract class BasicWhitelistConfiguration implements MutableWhitelistConfiguration {
public class BasicWhitelistConfiguration implements MutableWhitelistConfiguration {

private List<String> tags = null;

private Map<String, List<String>> attributes = null;

private Map<String, Map<String, String>> enforcedAttributes = null;

private Map<String, Map<String, List<String>>> protocols = null;

private List<String> tags() {
return Optional.ofNullable(tags).orElseGet(Collections::emptyList);
}

private Map<String, List<String>> attributes() {
return Optional.ofNullable(attributes).orElseGet(Collections::emptyMap);
}

private Map<String, Map<String, String>> enforcedAttributes() {
return Optional.ofNullable(enforcedAttributes).orElseGet(Collections::emptyMap);
}

private Map<String, Map<String, List<String>>> protocols() {
return Optional.ofNullable(protocols).orElseGet(Collections::emptyMap);
}

private List<String> tags = new ArrayList<>();
public MutableWhitelistConfiguration allowTag(String tagName) {
if (tags == null) {
tags = new ArrayList();
}
tags().add(tagName);
return this;
}

private Map<String, List<String>> attributes = new HashMap<>();
public void allowedTags(Consumer<String> fn) {
tags().forEach(fn);
}

private Map<String, Map<String, String>> enforcedAttributes = new HashMap<>();
public void allowedAttributes(BiConsumer<String, List<String>> fn) {
this.attributes().forEach(fn);
}

private Map<String, Map<String, List<String>>> protocols = new HashMap<>();
public void enforcedAttributes(BiConsumer<String, Map<String, String>> fn) {
enforcedAttributes().forEach(fn);
}

public void allowTag(String tagName) {
tags.add(tagName);
public void allowedProtocols(BiConsumer<String, Map<String, List<String>>> fn) {
protocols().forEach(fn);
}

public boolean allowsTag(String tagName) {
requireTagName(tagName);
return tags != null
&& tags.contains(tagName);
return tags().contains(tagName);
}

public boolean hasAllowedAttributes(String tagName) {
requireTagName(tagName);
return attributes != null
&& attributes.containsKey(tagName);
return attributes().containsKey(tagName);
}

public void allowAttribute(String tagName, String attrName) {
public MutableWhitelistConfiguration allowAttribute(String tagName, String attrName) {
requireTagName(tagName);
requireAttrName(attrName);
attributes.merge(tagName, list(attrName), Func::conj);
if (attributes == null) {
attributes = new HashMap();
}
attributes().merge(tagName, list(attrName), Func::concat);
return this;
}



public boolean allowsAttribute(String tagName, String attrName) {
requireAttrName(attrName);
return hasAllowedAttributes(tagName)
&& attributes.get(tagName) != null
&& attributes.get(tagName).contains(attrName);
&& attributes().get(tagName).contains(attrName);
}

public boolean hasEnforcedAttributes(String tagName) {
requireTagName(tagName);
return enforcedAttributes != null
&& enforcedAttributes.containsKey(tagName);
return enforcedAttributes().containsKey(tagName);
}

public boolean enforcesAttribute(String tagName, String attrName) {
requireAttrName(attrName);
return hasEnforcedAttributes(tagName)
&& enforcedAttributes.get(tagName) != null
&& enforcedAttributes.get(tagName).get(attrName) != null;
&& enforcedAttributes().get(tagName).get(attrName) != null;
}

public boolean enforcesAttribute(String tagName, String attrName, String enforcedValue) {
requireEnforcedValue(enforcedValue);
return enforcesAttribute(tagName, attrName)
&& enforcedAttributes.get(tagName).get(attrName).equals(enforcedValue);
&& enforcedAttributes().get(tagName).get(attrName).equals(enforcedValue);
}

public void enforceAttribute(String tagName, String attrName, String enforcedValue) {
public MutableWhitelistConfiguration enforceAttribute(String tagName, String attrName, String enforcedValue) {
requireTagName(tagName);
requireAttrName(attrName);
requireEnforcedValue(enforcedValue);
enforcedAttributes.merge(tagName, hashMap(attrName, enforcedValue), Func::merge1);
if (enforcedAttributes == null) {
enforcedAttributes = new HashMap();
}
enforcedAttributes().merge(tagName, hashMap(attrName, enforcedValue), Func::merge1);
return this;
}

public boolean hasAllowedProtocols(String tagName) {
requireTagName(tagName);
return protocols != null
&& protocols.containsKey(tagName);
return protocols().containsKey(tagName);
}

public boolean hasAllowedProtocols(String tagName, String attrName) {
requireAttrName(attrName);
return hasAllowedProtocols(tagName)
&& protocols.get(tagName) != null
&& protocols.get(tagName).containsKey(attrName);
&& protocols().get(tagName).containsKey(attrName);
}

public void allowProtocol(String tagName, String attrName, String protocol) {
public MutableWhitelistConfiguration allowProtocol(String tagName, String attrName, String protocol) {
requireTagName(tagName);
requireAttrName(attrName);
requireProtocol(protocol);
if (protocols == null) {
protocols = new HashMap();
}

protocols.merge(tagName, hashMap(attrName, list(protocol)), Func::merge2);
protocols().merge(tagName, hashMap(attrName, list(protocol)), Func::merge2);
return this;
}

public boolean allowsProtocol(String tagName, String attrName, String protocol) {
requireProtocol(protocol);
return hasAllowedProtocols(tagName, attrName)
&& protocols.get(tagName).get(attrName).contains(protocol);
}

private void requireTagName(String tagName) {
requireNonNull(tagName, "tagName cannot be null");
}

private void requireAttrName(String attrName) {
requireNonNull(attrName, "attrName cannot be null");
}

private void requireEnforcedValue(String enforcedValueCannot) {
requireNonNull(enforcedValueCannot, "enforcedValueCannot be null");
}

private void requireProtocol(String protocol) {
requireNonNull(protocol, "protocol cannot be null");
&& protocols().get(tagName).get(attrName).contains(protocol);
}

@Override
Expand All @@ -135,28 +165,50 @@ public Whitelist whitelist() {
return apply(Whitelist.none());
}

private void applyTags(Whitelist in) {
if (tags == null) {
return;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof BasicWhitelistConfiguration)) {
return false;
}
in.addTags(tags.toArray(new String[tags.size()]));
BasicWhitelistConfiguration that = (BasicWhitelistConfiguration) o;
return Objects.equals(tags(), that.tags()) &&
Objects.equals(attributes(), that.attributes()) &&
Objects.equals(enforcedAttributes(), that.enforcedAttributes()) &&
Objects.equals(protocols(), that.protocols());
}

@Override
public int hashCode() {
return Objects.hash(tags(), attributes(), enforcedAttributes(), protocols());
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder("BasicWhitelistConfiguration{");
sb.append("tags=").append(tags);
sb.append(", attributes=").append(attributes);
sb.append(", enforcedAttributes=").append(enforcedAttributes);
sb.append(", protocols=").append(protocols);
sb.append('}');
return sb.toString();
}

private void applyTags(Whitelist in) {
in.addTags(tags().toArray(new String[tags().size()]));
}

private void applyAttributes(Whitelist in) {
if (attributes == null) {
return;
}
for (Map.Entry<String, List<String>> attributeEntry : attributes.entrySet()) {
for (Map.Entry<String, List<String>> attributeEntry : attributes().entrySet()) {
in.addAttributes(attributeEntry.getKey(),
attributeEntry.getValue().toArray(new String[attributeEntry.getValue().size()]));
}
}

private void applyEnforcedAttributes(Whitelist in) {
if (enforcedAttributes == null) {
return;
}
for (Map.Entry<String, Map<String, String>> enforcedTag : enforcedAttributes.entrySet()) {
for (Map.Entry<String, Map<String, String>> enforcedTag : enforcedAttributes().entrySet()) {
final String tag = enforcedTag.getKey();
for (Map.Entry<String, String> enforcedAttribute : enforcedTag.getValue().entrySet()) {
final String attribute = enforcedAttribute.getKey();
Expand All @@ -170,10 +222,7 @@ private void applyEnforcedAttributes(Whitelist in) {
}

private void applyProtocols(Whitelist in) {
if (protocols == null) {
return;
}
for (Map.Entry<String, Map<String, List<String>>> enforcedTag : protocols.entrySet()) {
for (Map.Entry<String, Map<String, List<String>>> enforcedTag : protocols().entrySet()) {
final String tag = enforcedTag.getKey();
for (Map.Entry<String, List<String>> enforcedAttribute : enforcedTag.getValue().entrySet()) {
final String attribute = enforcedAttribute.getKey();
Expand All @@ -185,4 +234,20 @@ private void applyProtocols(Whitelist in) {
}
}
}

private void requireTagName(String tagName) {
requireNonNull(tagName, "tagName cannot be null");
}

private void requireAttrName(String attrName) {
requireNonNull(attrName, "attrName cannot be null");
}

private void requireEnforcedValue(String enforcedValueCannot) {
requireNonNull(enforcedValueCannot, "enforcedValueCannot be null");
}

private void requireProtocol(String protocol) {
requireNonNull(protocol, "protocol cannot be null");
}
}
49 changes: 0 additions & 49 deletions core/src/main/java/io/shick/jsoup/Func.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package io.shick.jsoup;

public interface MutableWhitelistConfiguration extends WhitelistConfiguration {
void allowTag(String tagName);
void enforceAttribute(String tagName, String attrName, String enforcedValue);
MutableWhitelistConfiguration allowTag(String tagName);

void allowProtocol(String tagName, String attrName, String protocol);
void allowAttribute(String tagName, String attrName);
MutableWhitelistConfiguration enforceAttribute(String tagName, String attrName, String enforcedValue);

MutableWhitelistConfiguration allowProtocol(String tagName, String attrName, String protocol);

MutableWhitelistConfiguration allowAttribute(String tagName, String attrName);
}
Loading

0 comments on commit 04d4eff

Please sign in to comment.