You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2020/04/22 07:08:35 UTC
[sling-slingfeature-maven-plugin] branch master updated: JSON-9362
: Use Apache Felix cm.json for JSON handling
This is an automated email from the ASF dual-hosted git repository.
cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-slingfeature-maven-plugin.git
The following commit(s) were added to refs/heads/master by this push:
new a62897c JSON-9362 : Use Apache Felix cm.json for JSON handling
a62897c is described below
commit a62897cec83062e423f676c395fb73e373d21862
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 22 09:08:23 2020 +0200
JSON-9362 : Use Apache Felix cm.json for JSON handling
---
pom.xml | 27 +++--
.../apache/sling/feature/maven/JSONFeatures.java | 110 +++++++++++++++++++++
.../apache/sling/feature/maven/ProjectHelper.java | 71 ++-----------
.../maven/mojos/AbstractIncludingFeatureMojo.java | 2 +-
.../feature/maven/mojos/UpdateVersionsMojo.java | 84 ++--------------
.../maven/mojos/AggregateFeaturesMojoTest.java | 26 ++---
6 files changed, 151 insertions(+), 169 deletions(-)
diff --git a/pom.xml b/pom.xml
index 11bc0bf..09e2af0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -136,7 +136,16 @@
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>6.0.0</version>
- <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-json_1.1_spec</artifactId>
+ <version>1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.johnzon</groupId>
+ <artifactId>johnzon-core</artifactId>
+ <version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
@@ -146,17 +155,17 @@
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.converter</artifactId>
- <version>1.0.10</version>
+ <version>1.0.14</version>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.configurator</artifactId>
- <version>1.0.10</version>
+ <artifactId>org.apache.felix.cm.json</artifactId>
+ <version>1.0.2</version>
</dependency>
<dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.commons.johnzon</artifactId>
- <version>1.1.0</version>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.util.function</artifactId>
+ <version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
@@ -166,7 +175,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.feature.io</artifactId>
- <version>1.3.0</version>
+ <version>1.3.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
@@ -284,7 +293,7 @@
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.utils</artifactId>
- <version>1.11.0</version>
+ <version>1.11.4</version>
</dependency>
<dependency>
<groupId>org.apache.maven.scm</groupId>
diff --git a/src/main/java/org/apache/sling/feature/maven/JSONFeatures.java b/src/main/java/org/apache/sling/feature/maven/JSONFeatures.java
new file mode 100644
index 0000000..85160fd
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/maven/JSONFeatures.java
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+package org.apache.sling.feature.maven;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Map;
+
+import javax.json.Json;
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonReader;
+import javax.json.JsonValue;
+import javax.json.JsonWriter;
+import javax.json.stream.JsonGenerator;
+
+import org.apache.felix.cm.json.Configurations;
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.io.json.FeatureJSONWriter;
+
+public class JSONFeatures {
+
+ public static final ArtifactId PLACEHOLDER_ID = new ArtifactId("_", "_", "1.0", null, null);
+
+ /**
+ * Read the feature and add the {@code id} attribute if missing
+ * @param reader The reader
+ * @param optionalId The artifact id to use if the {@code id} attribute is missing
+ * @param location The location
+ * @return The feature as a string
+ * @throws IOException If reading fails
+ */
+ public static String read(final Reader reader, final ArtifactId optionalId, final String location)
+ throws IOException {
+ JsonObject featureObj;
+ try (JsonReader jsonReader = Json.createReader(Configurations.jsonCommentAwareReader(reader))) {
+ featureObj = jsonReader.readObject();
+ if ( !featureObj.containsKey("id") ) {
+ final JsonObjectBuilder job = Json.createObjectBuilder();
+ job.add("id", optionalId.toMvnId());
+ for(final Map.Entry<String, JsonValue> prop : featureObj.entrySet() ) {
+ job.add(prop.getKey(), prop.getValue());
+ }
+ featureObj = job.build();
+ }
+ } catch ( final JsonException je) {
+ throw new IOException(je.getMessage(), je);
+ }
+
+ try ( final StringWriter writer = new StringWriter()) {
+ try ( final JsonWriter jsonWriter = Json.createWriter(writer)) {
+ jsonWriter.writeObject(featureObj);
+ }
+ return writer.toString();
+ }
+ }
+
+ /**
+ * Write the feature. If the id is the {@link #PLACEHOLDER_ID} then the id is not written out
+ * @param writer The writer
+ * @param feature The feature
+ * @throws IOException If anything goes wrong
+ */
+ public static void write(final Writer writer, final Feature feature) throws IOException {
+ if ( feature.getId().equals(PLACEHOLDER_ID)) {
+ // write feature with placeholder id
+ try ( final StringWriter stringWriter = new StringWriter()) {
+ FeatureJSONWriter.write(stringWriter, feature);
+
+ // read feature as json object
+ try (JsonReader jsonReader = Json.createReader(new StringReader(stringWriter.toString()))) {
+ final JsonObject featureObj = jsonReader.readObject();
+
+ // write feature object, except id property
+ try (final JsonGenerator generator = Json.createGenerator(writer)) {
+ generator.writeStartObject();
+
+ for (final Map.Entry<String, JsonValue> entry : featureObj.entrySet()) {
+ if ( !"id".equals(entry.getKey()) ) {
+ generator.write(entry.getKey(), entry.getValue());
+ }
+ }
+ generator.writeEnd();
+ }
+ }
+ }
+ } else {
+ FeatureJSONWriter.write(writer, feature);
+ }
+ }
+}
diff --git a/src/main/java/org/apache/sling/feature/maven/ProjectHelper.java b/src/main/java/org/apache/sling/feature/maven/ProjectHelper.java
index c6b17fd..f55ef30 100644
--- a/src/main/java/org/apache/sling/feature/maven/ProjectHelper.java
+++ b/src/main/java/org/apache/sling/feature/maven/ProjectHelper.java
@@ -35,13 +35,6 @@ import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
-import javax.json.Json;
-import javax.json.JsonObject;
-import javax.json.JsonReader;
-import javax.json.JsonValue;
-import javax.json.stream.JsonGenerator;
-
-import org.apache.felix.configurator.impl.json.JSMin;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
@@ -540,66 +533,18 @@ public abstract class ProjectHelper {
*/
public static String readFeatureFile(final MavenProject project, final File file,
final String suggestedClassifier) {
- final StringBuilder sb = new StringBuilder();
- try (final Reader reader = new FileReader(file)) {
- final char[] buf = new char[4096];
- int l = 0;
+ final ArtifactId fileId = new ArtifactId(project.getGroupId(),
+ project.getArtifactId(),
+ project.getVersion(),
+ suggestedClassifier,
+ FeatureConstants.PACKAGING_FEATURE);
- while ((l = reader.read(buf)) > 0) {
- sb.append(buf, 0, l);
- }
- } catch (final IOException io) {
- throw new RuntimeException("Unable to read feature " + file.getAbsolutePath(), io);
- }
- final String readJson = sb.toString();
-
- // minify JSON (remove comments)
- String json;
- try (final Writer out = new StringWriter(); final Reader in = new StringReader(readJson)) {
- final JSMin min = new JSMin(in, out);
- min.jsmin();
- json = out.toString();
+ // replace variables
+ try ( final Reader reader = new FileReader(file) ) {
+ return Substitution.replaceMavenVars(project, JSONFeatures.read(reader, fileId, file.getAbsolutePath()));
} catch (final IOException e) {
throw new RuntimeException("Unable to read feature file " + file.getAbsolutePath(), e);
}
-
- // check if "id" is set
- try (final JsonReader reader = Json.createReader(new StringReader(json))) {
- final JsonObject obj = reader.readObject();
- if (!obj.containsKey("id")) {
- final StringBuilder isb = new StringBuilder();
- isb.append(project.getGroupId());
- isb.append(':');
- isb.append(project.getArtifactId());
- isb.append(':');
- isb.append(FeatureConstants.PACKAGING_FEATURE);
-
- if (suggestedClassifier != null) {
- isb.append(':');
- isb.append(suggestedClassifier);
- }
- isb.append(':');
- isb.append(project.getVersion());
-
- final StringWriter writer = new StringWriter();
-
- try (final JsonGenerator generator = Json.createGenerator(writer)) {
- generator.writeStartObject();
-
- generator.write("id", isb.toString());
-
- for (final Map.Entry<String, JsonValue> entry : obj.entrySet()) {
- generator.write(entry.getKey(), entry.getValue());
- }
- generator.writeEnd();
- }
-
- json = writer.toString();
- }
- }
-
- // replace variables
- return Substitution.replaceMavenVars(project, json);
}
public static void checkFeatureId(final MavenProject project, final Feature feature) {
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/AbstractIncludingFeatureMojo.java b/src/main/java/org/apache/sling/feature/maven/mojos/AbstractIncludingFeatureMojo.java
index 2424321..6dcef11 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/AbstractIncludingFeatureMojo.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/AbstractIncludingFeatureMojo.java
@@ -39,7 +39,7 @@ import edu.emory.mathcs.backport.java.util.Collections;
public abstract class AbstractIncludingFeatureMojo extends AbstractFeatureMojo {
/**
- * Get all selected features for the provided configuratio
+ * Get all selected features for the provided configuration
* @param config The selection configuration
* @return An ordered map of features
* @throws MojoExecutionException
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/UpdateVersionsMojo.java b/src/main/java/org/apache/sling/feature/maven/mojos/UpdateVersionsMojo.java
index e4280d4..dcb4244 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/UpdateVersionsMojo.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/UpdateVersionsMojo.java
@@ -21,6 +21,7 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
+import java.io.StringReader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
@@ -32,9 +33,6 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
-import javax.json.stream.JsonGenerator;
-import javax.json.stream.JsonParsingException;
-
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
@@ -53,7 +51,7 @@ import org.apache.sling.feature.Extension;
import org.apache.sling.feature.ExtensionType;
import org.apache.sling.feature.Feature;
import org.apache.sling.feature.io.json.FeatureJSONReader;
-import org.apache.sling.feature.io.json.FeatureJSONWriter;
+import org.apache.sling.feature.maven.JSONFeatures;
import org.apache.sling.feature.maven.ProjectHelper;
import org.codehaus.mojo.versions.api.ArtifactVersions;
import org.codehaus.mojo.versions.api.DefaultVersionsHelper;
@@ -208,9 +206,11 @@ public class UpdateVersionsMojo extends AbstractIncludingFeatureMojo {
private Feature readRawFeature(final String fileName) throws MojoExecutionException {
// we need to read the raw file
- final File out = new File(fileName);
- try (final Reader r = new FileReader(out)) {
- return SimpleFeatureJSONReader.read(r, fileName);
+ try (final Reader r = new FileReader(new File(fileName))) {
+ final String json = JSONFeatures.read(r, JSONFeatures.PLACEHOLDER_ID, fileName);
+ try ( final Reader featureReader = new StringReader(json)) {
+ return FeatureJSONReader.read(featureReader, fileName);
+ }
} catch (final IOException e) {
throw new MojoExecutionException("Unable to read feature file " + fileName, e);
}
@@ -280,7 +280,7 @@ public class UpdateVersionsMojo extends AbstractIncludingFeatureMojo {
if (updateVersions(entry.getKey(), rawFeature, result, globalPropertyUpdates) && !dryRun) {
try (final Writer w = new FileWriter(new File(entry.getKey()))) {
- SimpleFeatureJSONWriter.write(w, rawFeature);
+ JSONFeatures.write(w, rawFeature);
} catch (final IOException e) {
throw new MojoExecutionException("Unable to write feature file " + entry.getValue(), e);
}
@@ -471,74 +471,6 @@ public class UpdateVersionsMojo extends AbstractIncludingFeatureMojo {
public Map<String, String> propertyUpdates = new HashMap<>();
}
- public static class SimpleFeatureJSONReader extends FeatureJSONReader {
-
- static final ArtifactId PLACEHOLDER_ID = new ArtifactId("_", "_", "1.0", null, null);
-
- /**
- * Private constructor
- * @param location Optional location
- */
- protected SimpleFeatureJSONReader(final String location) {
- super(location);
- }
-
- @Override
- protected ArtifactId getFeatureId(Map<String, Object> map) throws IOException {
- final ArtifactId id;
- if ( !map.containsKey("id") ) {
- id = PLACEHOLDER_ID;
- } else {
- id = super.getFeatureId(map);
- }
- return id;
- }
-
- /**
- * Read a new feature from the reader
- * The reader is not closed. It is up to the caller to close the reader.
- *
- * @param reader The reader for the feature
- * @param location Optional location
- * @return The read feature
- * @throws IOException If an IO errors occurs or the JSON is invalid.
- */
- public static Feature read(final Reader reader, final String location)
- throws IOException {
- try {
- final SimpleFeatureJSONReader mr = new SimpleFeatureJSONReader(location);
- return mr.readFeature(reader);
- } catch (final IllegalStateException | IllegalArgumentException | JsonParsingException e) {
- throw new IOException(e);
- }
- }
- }
-
- public static class SimpleFeatureJSONWriter extends FeatureJSONWriter {
-
- private SimpleFeatureJSONWriter() {}
-
- /**
- * Writes the feature to the writer.
- * The writer is not closed.
- * @param writer Writer
- * @param feature Feature
- * @throws IOException If writing fails
- */
- public static void write(final Writer writer, final Feature feature)
- throws IOException {
- final SimpleFeatureJSONWriter w = new SimpleFeatureJSONWriter();
- w.writeFeature(writer, feature);
- }
-
- @Override
- protected void writeFeatureId(JsonGenerator generator, Feature feature) {
- if ( !feature.getId().equals(SimpleFeatureJSONReader.PLACEHOLDER_ID) ) {
- super.writeFeatureId(generator, feature);
- }
- }
- }
-
private String getVersion(final Map.Entry<Dependency, ArtifactVersions> entry, final UpdateScope scope) {
ArtifactVersion latest;
if (entry.getValue().isCurrentVersionDefined()) {
diff --git a/src/test/java/org/apache/sling/feature/maven/mojos/AggregateFeaturesMojoTest.java b/src/test/java/org/apache/sling/feature/maven/mojos/AggregateFeaturesMojoTest.java
index d4ecdfa..f1d0ce4 100644
--- a/src/test/java/org/apache/sling/feature/maven/mojos/AggregateFeaturesMojoTest.java
+++ b/src/test/java/org/apache/sling/feature/maven/mojos/AggregateFeaturesMojoTest.java
@@ -40,9 +40,8 @@ import java.util.Properties;
import java.util.Set;
import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.execution.MavenSession;
@@ -62,8 +61,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
@SuppressWarnings("deprecation")
public class AggregateFeaturesMojoTest {
@@ -402,7 +399,6 @@ public class AggregateFeaturesMojoTest {
assertEquals(expectedConfigs, actualConfigs);
}
- @SuppressWarnings("unchecked")
@Test
public void testReadFeatureFromArtifact() throws Exception {
File featureFile = new File(
@@ -438,6 +434,11 @@ public class AggregateFeaturesMojoTest {
.thenReturn(featureMap);
Mockito.when(mockProj.getContextValue(Preprocessor.class.getName())).thenReturn(Boolean.TRUE);
+ final Artifact fileArtifact = new DefaultArtifact(dep.getGroupId(), dep.getArtifactId(),
+ dep.getVersion(), Artifact.SCOPE_COMPILE, dep.getType(), dep.getClassifier(), Mockito.mock(org.apache.maven.artifact.handler.ArtifactHandler.class));
+ fileArtifact.setFile(featureFile);
+
+ Mockito.when(mockProj.getAttachedArtifacts()).thenReturn(Collections.singletonList(fileArtifact));
AggregateFeaturesMojo af = new AggregateFeaturesMojo();
fc.classifier = "mynewfeature";
af.aggregates = Collections.singletonList(fc);
@@ -448,21 +449,6 @@ public class AggregateFeaturesMojoTest {
af.features = featureFile.getParentFile();
af.artifactResolver = Mockito.mock(ArtifactResolver.class);
- Mockito.doAnswer(new Answer<Void>() {
- @Override
- public Void answer(InvocationOnMock invocation) throws Throwable {
- Artifact artifact = invocation.getArgumentAt(0, Artifact.class);
- if (artifact.getGroupId().equals(dep.getGroupId())
- && artifact.getArtifactId().equals(dep.getArtifactId())
- && artifact.getVersion().equals(dep.getVersion())
- && artifact.getClassifier().equals(dep.getClassifier())
- && artifact.getType().equals(dep.getType())) {
- artifact.setFile(featureFile);
- return null;
- }
- throw new ArtifactResolutionException("Not found", artifact);
- }
- }).when(af.artifactResolver).resolve(Mockito.any(Artifact.class), Mockito.anyList(), Mockito.any(ArtifactRepository.class));
af.execute();
Feature genFeat = featureMap.get(":aggregate:mynewfeature:T");