Author: pauls Date: Mon Jul 31 21:56:25 2017 New Revision: 1803576 URL: http://svn.apache.org/viewvc?rev=1803576&view=rev Log: Implement Attribute and Directive marshal and unmarshal.
Modified: sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/json/FeatureJSONReader.java sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/json/FeatureJSONWriter.java sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestParser.java sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestUtil.java Modified: sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/json/FeatureJSONReader.java URL: http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/json/FeatureJSONReader.java?rev=1803576&r1=1803575&r2=1803576&view=diff ============================================================================== --- sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/json/FeatureJSONReader.java (original) +++ sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/json/FeatureJSONReader.java Mon Jul 31 21:56:25 2017 @@ -32,8 +32,13 @@ import org.apache.sling.feature.Capabili import org.apache.sling.feature.Feature; import org.apache.sling.feature.Include; import org.apache.sling.feature.Requirement; +import org.apache.sling.feature.support.util.LambdaUtil; import org.apache.sling.feature.support.util.ManifestUtil; +import static org.apache.sling.feature.support.util.LambdaUtil.rethrowBiConsumer; +import static org.apache.sling.feature.support.util.ManifestUtil.unmarshalAttribute; +import static org.apache.sling.feature.support.util.ManifestUtil.unmarshalDirective; + /** * This class offers a method to read a {@code Feature} using a {@code Reader} instance. */ @@ -284,14 +289,14 @@ public class FeatureJSONReader extends J checkType("Requirement attributes", obj.get(JSONConstants.REQCAP_ATTRIBUTES), Map.class); @SuppressWarnings("unchecked") final Map<String, Object> attrs = (Map<String, Object>)obj.get(JSONConstants.REQCAP_ATTRIBUTES); - attrs.forEach((key, value) -> ManifestUtil.unmarshallAttribute(key, value, r.getAttributes()::put)); + attrs.forEach(rethrowBiConsumer((key, value) -> unmarshalAttribute(key, value, r.getAttributes()::put))); } if ( obj.containsKey(JSONConstants.REQCAP_DIRECTIVES) ) { checkType("Requirement directives", obj.get(JSONConstants.REQCAP_DIRECTIVES), Map.class); @SuppressWarnings("unchecked") final Map<String, Object> dirs = (Map<String, Object>)obj.get(JSONConstants.REQCAP_DIRECTIVES); - dirs.forEach((key, value) -> ManifestUtil.unmarshallDirective(key, value, r.getDirectives()::put)); + dirs.forEach(rethrowBiConsumer((key, value) -> unmarshalDirective(key, value, r.getDirectives()::put))); } } } @@ -321,14 +326,14 @@ public class FeatureJSONReader extends J checkType("Capability attributes", obj.get(JSONConstants.REQCAP_ATTRIBUTES), Map.class); @SuppressWarnings("unchecked") final Map<String, Object> attrs = (Map<String, Object>)obj.get(JSONConstants.REQCAP_ATTRIBUTES); - attrs.forEach((key, value) -> ManifestUtil.unmarshallAttribute(key, value, c.getAttributes()::put)); + attrs.forEach(rethrowBiConsumer((key, value) -> unmarshalAttribute(key, value, c.getAttributes()::put))); } if ( obj.containsKey(JSONConstants.REQCAP_DIRECTIVES) ) { checkType("Capability directives", obj.get(JSONConstants.REQCAP_DIRECTIVES), Map.class); @SuppressWarnings("unchecked") final Map<String, Object> dirs = (Map<String, Object>) obj.get(JSONConstants.REQCAP_DIRECTIVES); - dirs.forEach((key, value) -> ManifestUtil.unmarshallDirective(key, value, c.getDirectives()::put)); + dirs.forEach(rethrowBiConsumer((key, value) -> unmarshalDirective(key, value, c.getDirectives()::put))); } } } Modified: sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/json/FeatureJSONWriter.java URL: http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/json/FeatureJSONWriter.java?rev=1803576&r1=1803575&r2=1803576&view=diff ============================================================================== --- sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/json/FeatureJSONWriter.java (original) +++ sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/json/FeatureJSONWriter.java Mon Jul 31 21:56:25 2017 @@ -34,6 +34,9 @@ import org.apache.sling.feature.Include; import org.apache.sling.feature.Requirement; import org.apache.sling.feature.support.util.ManifestUtil; +import static org.apache.sling.feature.support.util.ManifestUtil.marshalAttribute; +import static org.apache.sling.feature.support.util.ManifestUtil.marshalDirective; + /** * Simple JSON writer for a feature @@ -154,12 +157,12 @@ public class FeatureJSONWriter extends J w.write(JSONConstants.REQCAP_NAMESPACE, req.getNamespace()); if ( !req.getAttributes().isEmpty() ) { w.writeStartObject(JSONConstants.REQCAP_ATTRIBUTES); - req.getAttributes().forEach((key, value) -> ManifestUtil.marshallAttribute(key, value, w::write)); + req.getAttributes().forEach((key, value) -> marshalAttribute(key, value, w::write)); w.writeEnd(); } if ( !req.getDirectives().isEmpty() ) { w.writeStartObject(JSONConstants.REQCAP_DIRECTIVES); - req.getDirectives().forEach((key, value) -> ManifestUtil.marshallDirective(key, value, w::write)); + req.getDirectives().forEach((key, value) -> marshalDirective(key, value, w::write)); w.writeEnd(); } w.writeEnd(); @@ -176,12 +179,12 @@ public class FeatureJSONWriter extends J w.write(JSONConstants.REQCAP_NAMESPACE, cap.getNamespace()); if ( !cap.getAttributes().isEmpty() ) { w.writeStartObject(JSONConstants.REQCAP_ATTRIBUTES); - cap.getAttributes().forEach((key, value) -> ManifestUtil.marshallAttribute(key, value, w::write)); + cap.getAttributes().forEach((key, value) -> marshalAttribute(key, value, w::write)); w.writeEnd(); } if ( !cap.getDirectives().isEmpty() ) { w.writeStartObject(JSONConstants.REQCAP_DIRECTIVES); - cap.getDirectives().forEach((key, value) -> ManifestUtil.marshallDirective(key, value, w::write)); + cap.getDirectives().forEach((key, value) -> marshalDirective(key, value, w::write)); w.writeEnd(); } w.writeEnd(); Modified: sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestParser.java URL: http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestParser.java?rev=1803576&r1=1803575&r2=1803576&view=diff ============================================================================== --- sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestParser.java (original) +++ sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestParser.java Mon Jul 31 21:56:25 2017 @@ -210,7 +210,7 @@ public class ManifestParser return reqList; } - private static List<ParsedHeaderClause> normalizeCapabilityClauses( + static List<ParsedHeaderClause> normalizeCapabilityClauses( List<ParsedHeaderClause> clauses, String mv) throws BundleException { @@ -315,7 +315,7 @@ public class ManifestParser return clauses; } - private static List<Capability> convertProvideCapabilities( + static List<Capability> convertProvideCapabilities( List<ParsedHeaderClause> clauses) throws BundleException { @@ -699,7 +699,7 @@ public class ManifestParser return "(" + ExecutionEnvironmentNamespace.CAPABILITY_VERSION_ATTRIBUTE + "=" + ver + ")"; } - private static List<ParsedHeaderClause> normalizeRequireClauses(List<ParsedHeaderClause> clauses, String mv) + static List<ParsedHeaderClause> normalizeRequireClauses(List<ParsedHeaderClause> clauses, String mv) { // R3 bundles cannot require other bundles. if (!mv.equals("2")) @@ -791,7 +791,7 @@ public class ManifestParser private static final int VALUE = 16; @SuppressWarnings({ "unchecked", "rawtypes" }) - private static List<ParsedHeaderClause> parseStandardHeader(String header) + static List<ParsedHeaderClause> parseStandardHeader(String header) { List<ParsedHeaderClause> clauses = new ArrayList<ParsedHeaderClause>(); if (header == null) Modified: sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestUtil.java URL: http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestUtil.java?rev=1803576&r1=1803575&r2=1803576&view=diff ============================================================================== --- sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestUtil.java (original) +++ sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestUtil.java Mon Jul 31 21:56:25 2017 @@ -21,17 +21,20 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Function; import java.util.jar.JarFile; import java.util.jar.Manifest; +import java.util.stream.Collectors; import org.apache.sling.commons.osgi.ManifestHeader; import org.apache.sling.feature.Capability; import org.apache.sling.feature.Requirement; import org.osgi.framework.Constants; +import org.osgi.framework.Version; + +import static org.apache.sling.feature.support.util.ManifestParser.convertProvideCapabilities; +import static org.apache.sling.feature.support.util.ManifestParser.normalizeCapabilityClauses; +import static org.apache.sling.feature.support.util.ManifestParser.parseStandardHeader; public class ManifestUtil { @@ -96,29 +99,74 @@ public class ManifestUtil { return parser.getRequirements(); } - public static void unmarshallAttribute(String key, Object value, BiConsumer<String, Object> sink) { - unmarshallAttributeOrDirective(key, value, sink); + public static void unmarshalAttribute(String key, Object value, BiConsumer<String, Object> sink) throws IOException { + unmarshal(key + "=" + value, sink); + } + + public static void unmarshalDirective(String key, Object value, BiConsumer<String, Object> sink) throws IOException { + unmarshal(key + ":=" + value, sink); } - public static void unmarshallDirective(String key, Object value, BiConsumer<String, Object> sink) { - unmarshallAttributeOrDirective(key, value, sink); + private static void unmarshal(String header, BiConsumer<String, Object> sink) throws IOException { + try { + convertProvideCapabilities( + normalizeCapabilityClauses(parseStandardHeader("foo;" + header), "2")) + .forEach(capability -> capability.getAttributes().forEach(sink)); + } catch (Exception e) { + throw new IOException(e); + } } - private static void unmarshallAttributeOrDirective(String key, Object value, BiConsumer<String, Object> sink) { - // TODO: parse Attribute Or Directive correctly - sink.accept(key, value.toString()); + public static void marshalAttribute(String key, Object value, BiConsumer<String, String> sink) { + marshal(key, value, sink); } - public static void marshallAttribute(String key, Object value, BiConsumer<String, String> sink) { - marshallAttributeOrDirective(key, value, sink); + public static void marshalDirective(String key, Object value, BiConsumer<String, String> sink) { + marshal(key, value, sink); } - public static void marshallDirective(String key, Object value, BiConsumer<String, String> sink) { - marshallAttributeOrDirective(key, value, sink); + private static void marshal(String key, Object value, BiConsumer<String, String> sink) { + StringBuilder keyBuilder = new StringBuilder(key); + if (value instanceof List) { + List list = (List) value; + keyBuilder.append(":List"); + if (!list.isEmpty()) { + String type = type(list.get(0)); + if (!type.equals("String")) { + keyBuilder.append('<').append(type).append('>'); + } + value = list.stream().map( + v -> v.toString().replace(",", "\\,") + ).collect(Collectors.joining(",")); + } + else { + value = ""; + } + } + else { + String type = type(value); + if (!type.equals("String")) { + keyBuilder.append(':').append(type); + } + } + sink.accept(keyBuilder.toString(), value.toString()); } - private static void marshallAttributeOrDirective(String key, Object value, BiConsumer<String, String> sink) { - // TODO: encode Attribute Or Directive correctly - sink.accept(key, value.toString()); + private static String type(Object value) { + if (value instanceof Long) { + return "Long"; + } + else if (value instanceof Double) + { + return "Double"; + } + else if (value instanceof Version) + { + return "Version"; + } + else + { + return "String"; + } } }