Author: cziegeler
Date: Fri Jul 28 14:55:05 2017
New Revision: 1803280
URL: http://svn.apache.org/viewvc?rev=1803280&view=rev
Log:
Refactor duplicate merge code
Added:
sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/BuilderUtil.java
(with props)
Modified:
sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/ApplicationBuilder.java
sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/FeatureBuilder.java
Modified:
sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/ApplicationBuilder.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/ApplicationBuilder.java?rev=1803280&r1=1803279&r2=1803280&view=diff
==============================================================================
---
sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/ApplicationBuilder.java
(original)
+++
sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/ApplicationBuilder.java
Fri Jul 28 14:55:05 2017
@@ -16,26 +16,14 @@
*/
package org.apache.sling.feature.process;
-import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonObject;
-import javax.json.JsonStructure;
-import javax.json.JsonValue;
-import javax.json.JsonValue.ValueType;
-
import org.apache.sling.feature.Application;
-import org.apache.sling.feature.Artifact;
import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Extension;
import org.apache.sling.feature.Feature;
/**
@@ -165,134 +153,9 @@ public class ApplicationBuilder {
}
private static void merge(final Application target, final Feature source) {
- // bundles
- for(final Map.Entry<Integer, List<Artifact>> entry :
source.getBundles().getBundlesByStartLevel().entrySet()) {
- for(final Artifact a : entry.getValue()) {
- // version handling - highest version wins
- final Map.Entry<Integer, Artifact> existing =
target.getBundles().getSame(a.getId());
- boolean replace = true;
- if ( existing != null &&
existing.getValue().getId().getOSGiVersion().compareTo(a.getId().getOSGiVersion())
> 0 ) {
- replace = false;
- }
- if ( replace ) {
- target.getBundles().removeSame(a.getId());
- target.getBundles().add(entry.getKey(), a);
- }
- }
- }
-
- // configurations
- for(final Configuration cfg : source.getConfigurations()) {
- boolean found = false;
- for(final Configuration current : target.getConfigurations()) {
- if ( current.compareTo(cfg) == 0 ) {
- found = true;
- final Enumeration<String> i = cfg.getProperties().keys();
- while ( i.hasMoreElements() ) {
- final String key = i.nextElement();
- current.getProperties().put(key,
cfg.getProperties().get(key));
- }
- break;
- }
- }
- if ( !found ) {
- target.getConfigurations().add(cfg);
- }
- }
-
- // framework properties
-
target.getFrameworkProperties().putAll(source.getFrameworkProperties());
-
- // extensions
- for(final Extension ext : source.getExtensions()) {
- boolean found = false;
- for(final Extension current : target.getExtensions()) {
- if ( current.getName().equals(ext.getName()) ) {
- found = true;
- if ( current.getType() != ext.getType() ) {
- throw new IllegalStateException("Found different types
for extension " + current.getName()
- + " : " + current.getType() + " and " + ext.getType());
- }
- switch ( current.getType() ) {
- case TEXT : // simply append
- current.setText(current.getText() + "\n" +
ext.getText());
- break;
- case JSON : final JsonStructure struct1;
- try ( final StringReader reader = new
StringReader(current.getJSON()) ) {
- struct1 =
Json.createReader(reader).read();
- }
- final JsonStructure struct2;
- try ( final StringReader reader = new
StringReader(ext.getJSON()) ) {
- struct2 =
Json.createReader(reader).read();
- }
-
- if ( struct1.getValueType() !=
struct2.getValueType() ) {
- throw new IllegalStateException("Found
different JSON types for extension " + current.getName()
- + " : " + struct1.getValueType() + "
and " + struct2.getValueType());
- }
- if ( struct1.getValueType() ==
ValueType.ARRAY ) {
- // array is append
- final JsonArray a1 =
(JsonArray)struct1;
- final JsonArray a2 =
(JsonArray)struct2;
- for(final JsonValue val : a2) {
- a1.add(val);
- }
- } else {
- // object is merge
- merge((JsonObject)struct1,
(JsonObject)struct2);
- }
- break;
-
- case ARTIFACTS : for(final Artifact a :
ext.getArtifacts()) {
- // remove same artifact - latest
version wins (not highest)
- boolean add = true;
- for(final Artifact targetArtifact
: current.getArtifacts()) {
- if (
targetArtifact.getId().isSame(a.getId()) ) {
- if (
targetArtifact.getId().getOSGiVersion().compareTo(a.getId().getOSGiVersion()) >
0 ) {
- add = false;
- } else {
-
current.getArtifacts().remove(targetArtifact);
- }
- break;
- }
- }
- if ( add ) {
- current.getArtifacts().add(a);
- }
- }
- break;
-
- }
- }
- }
- if ( !found ) {
- target.getExtensions().add(ext);
- }
- }
- }
-
- private static void merge(final JsonObject obj1, final JsonObject obj2) {
- for(final Map.Entry<String, JsonValue> entry : obj2.entrySet()) {
- if ( !obj1.containsKey(entry.getKey()) ) {
- obj1.put(entry.getKey(), entry.getValue());
- } else {
- final JsonValue oldValue = obj1.get(entry.getKey());
- if ( oldValue.getValueType() !=
entry.getValue().getValueType() ) {
- // new type wins
- obj1.put(entry.getKey(), entry.getValue());
- } else if ( oldValue.getValueType() == ValueType.ARRAY ) {
- final JsonArray a1 = (JsonArray)oldValue;
- final JsonArray a2 = (JsonArray)entry.getValue();
- for(final JsonValue val : a2) {
- a1.add(val);
- }
-
- } else if ( oldValue.getValueType() == ValueType.OBJECT ) {
- merge((JsonObject)oldValue, (JsonObject)entry.getValue());
- } else {
- obj1.put(entry.getKey(), entry.getValue());
- }
- }
- }
+ BuilderUtil.mergeBundles(target.getBundles(), source.getBundles(),
BuilderUtil.ArtifactMerge.HIGHEST);
+ BuilderUtil.mergeConfigurations(target.getConfigurations(),
source.getConfigurations());
+ BuilderUtil.mergeFrameworkProperties(target.getFrameworkProperties(),
source.getFrameworkProperties());
+ BuilderUtil.mergeExtensions(target.getExtensions(),
source.getExtensions(), BuilderUtil.ArtifactMerge.HIGHEST);
}
}
Added:
sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/BuilderUtil.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/BuilderUtil.java?rev=1803280&view=auto
==============================================================================
---
sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/BuilderUtil.java
(added)
+++
sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/BuilderUtil.java
Fri Jul 28 14:55:05 2017
@@ -0,0 +1,220 @@
+/*
+ * 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.process;
+
+import java.io.StringReader;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+import javax.json.JsonValue.ValueType;
+
+import org.apache.sling.feature.Artifact;
+import org.apache.sling.feature.Bundles;
+import org.apache.sling.feature.Capability;
+import org.apache.sling.feature.Configuration;
+import org.apache.sling.feature.Configurations;
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.Extensions;
+import org.apache.sling.feature.KeyValueMap;
+import org.apache.sling.feature.Requirement;
+
+/**
+ * Utility methods for the builders
+ */
+class BuilderUtil {
+
+ public enum ArtifactMerge {
+ LATEST,
+ HIGHEST
+ };
+
+ // bundles
+ static void mergeBundles(final Bundles target,
+ final Bundles source,
+ final ArtifactMerge artifactMergeAlg) {
+ for(final Map.Entry<Integer, List<Artifact>> entry :
source.getBundlesByStartLevel().entrySet()) {
+ for(final Artifact a : entry.getValue()) {
+ // version handling - use provided algorithm
+ boolean replace = true;
+ if ( artifactMergeAlg == ArtifactMerge.HIGHEST ) {
+ final Map.Entry<Integer, Artifact> existing =
target.getSame(a.getId());
+ if ( existing != null &&
existing.getValue().getId().getOSGiVersion().compareTo(a.getId().getOSGiVersion())
> 0 ) {
+ replace = false;
+ }
+ }
+ if ( replace ) {
+ target.removeSame(a.getId());
+ target.add(entry.getKey(), a);
+ }
+ }
+ }
+ }
+
+ // configurations - merge / override
+ static void mergeConfigurations(final Configurations target, final
Configurations source) {
+ for(final Configuration cfg : source) {
+ boolean found = false;
+ for(final Configuration current : target) {
+ if ( current.compareTo(cfg) == 0 ) {
+ found = true;
+ // merge / override properties
+ final Enumeration<String> i = cfg.getProperties().keys();
+ while ( i.hasMoreElements() ) {
+ final String key = i.nextElement();
+ current.getProperties().put(key,
cfg.getProperties().get(key));
+ }
+ break;
+ }
+ }
+ if ( !found ) {
+ target.add(cfg);
+ }
+ }
+ }
+
+ // framework properties (add/merge)
+ static void mergeFrameworkProperties(final KeyValueMap target, final
KeyValueMap source) {
+ target.putAll(source);
+ }
+
+ // requirements (add)
+ static void mergeRequirements(final List<Requirement> target, final
List<Requirement> source) {
+ for(final Requirement req : source) {
+ if ( !target.contains(req) ) {
+ target.add(req);
+ }
+ }
+ }
+
+ // capabilities (add)
+ static void mergeCapabilities(final List<Capability> target, final
List<Capability> source) {
+ for(final Capability cap : source) {
+ if ( !target.contains(cap) ) {
+ target.add(cap);
+ }
+ }
+ }
+
+ // extensions (add/merge)
+ static void mergeExtensions(final Extensions target,
+ final Extensions source,
+ final ArtifactMerge artifactMergeAlg) {
+ for(final Extension ext : source) {
+ boolean found = false;
+ for(final Extension current : target) {
+ if ( current.getName().equals(ext.getName()) ) {
+ found = true;
+ if ( current.getType() != ext.getType() ) {
+ throw new IllegalStateException("Found different types
for extension " + current.getName()
+ + " : " + current.getType() + " and " + ext.getType());
+ }
+ switch ( current.getType() ) {
+ case TEXT : // simply append
+ current.setText(current.getText() + "\n" +
ext.getText());
+ break;
+ case JSON : final JsonStructure struct1;
+ try ( final StringReader reader = new
StringReader(current.getJSON()) ) {
+ struct1 =
Json.createReader(reader).read();
+ }
+ final JsonStructure struct2;
+ try ( final StringReader reader = new
StringReader(ext.getJSON()) ) {
+ struct2 =
Json.createReader(reader).read();
+ }
+
+ if ( struct1.getValueType() !=
struct2.getValueType() ) {
+ throw new IllegalStateException("Found
different JSON types for extension " + current.getName()
+ + " : " + struct1.getValueType() + "
and " + struct2.getValueType());
+ }
+ if ( struct1.getValueType() ==
ValueType.ARRAY ) {
+ // array is append
+ final JsonArray a1 =
(JsonArray)struct1;
+ final JsonArray a2 =
(JsonArray)struct2;
+ for(final JsonValue val : a2) {
+ a1.add(val);
+ }
+ } else {
+ // object is merge
+ merge((JsonObject)struct1,
(JsonObject)struct2);
+ }
+ break;
+
+ case ARTIFACTS : for(final Artifact a :
ext.getArtifacts()) {
+ // use artifactMergeAlg
+ boolean add = true;
+ for(final Artifact targetArtifact
: current.getArtifacts()) {
+ if (
targetArtifact.getId().isSame(a.getId()) ) {
+ if ( artifactMergeAlg ==
ArtifactMerge.HIGHEST ) {
+ if (
targetArtifact.getId().getOSGiVersion().compareTo(a.getId().getOSGiVersion()) >
0 ) {
+ add = false;
+ } else {
+
current.getArtifacts().remove(targetArtifact);
+ }
+ } else { // latest
+
+
current.getArtifacts().remove(targetArtifact);
+ }
+ break;
+ }
+ }
+
+ if ( add ) {
+ current.getArtifacts().add(a);
+ }
+
+ }
+ break;
+
+ }
+ }
+ }
+ if ( !found ) {
+ target.add(ext);
+ }
+ }
+ }
+
+ private static void merge(final JsonObject obj1, final JsonObject obj2) {
+ for(final Map.Entry<String, JsonValue> entry : obj2.entrySet()) {
+ if ( !obj1.containsKey(entry.getKey()) ) {
+ obj1.put(entry.getKey(), entry.getValue());
+ } else {
+ final JsonValue oldValue = obj1.get(entry.getKey());
+ if ( oldValue.getValueType() !=
entry.getValue().getValueType() ) {
+ // new type wins
+ obj1.put(entry.getKey(), entry.getValue());
+ } else if ( oldValue.getValueType() == ValueType.ARRAY ) {
+ final JsonArray a1 = (JsonArray)oldValue;
+ final JsonArray a2 = (JsonArray)entry.getValue();
+ for(final JsonValue val : a2) {
+ a1.add(val);
+ }
+
+ } else if ( oldValue.getValueType() == ValueType.OBJECT ) {
+ merge((JsonObject)oldValue, (JsonObject)entry.getValue());
+ } else {
+ obj1.put(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+ }
+}
Propchange:
sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/BuilderUtil.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/BuilderUtil.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Modified:
sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/FeatureBuilder.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/FeatureBuilder.java?rev=1803280&r1=1803279&r2=1803280&view=diff
==============================================================================
---
sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/FeatureBuilder.java
(original)
+++
sling/whiteboard/cziegeler/feature/src/main/java/org/apache/sling/feature/process/FeatureBuilder.java
Fri Jul 28 14:55:05 2017
@@ -16,29 +16,18 @@
*/
package org.apache.sling.feature.process;
-import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonObject;
-import javax.json.JsonStructure;
-import javax.json.JsonValue;
-import javax.json.JsonValue.ValueType;
-
import org.apache.sling.feature.Artifact;
import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Capability;
import org.apache.sling.feature.Configuration;
import org.apache.sling.feature.Extension;
import org.apache.sling.feature.Feature;
import org.apache.sling.feature.Include;
-import org.apache.sling.feature.Requirement;
public class FeatureBuilder {
@@ -215,132 +204,12 @@ public class FeatureBuilder {
}
private static void merge(final Feature target, final Feature source) {
- // bundles
- for(final Map.Entry<Integer, List<Artifact>> entry :
source.getBundles().getBundlesByStartLevel().entrySet()) {
- for(final Artifact a : entry.getValue()) {
- // latest version wins (not highest!)
- target.getBundles().removeSame(a.getId());
- target.getBundles().add(entry.getKey(), a);
- }
- }
-
- // configurations
- for(final Configuration cfg : source.getConfigurations()) {
- boolean found = false;
- for(final Configuration current : target.getConfigurations()) {
- if ( current.compareTo(cfg) == 0 ) {
- found = true;
- // merge / override properties
- final Enumeration<String> i = cfg.getProperties().keys();
- while ( i.hasMoreElements() ) {
- final String key = i.nextElement();
- current.getProperties().put(key,
cfg.getProperties().get(key));
- }
- break;
- }
- }
- if ( !found ) {
- target.getConfigurations().add(cfg);
- }
- }
-
- // framework properties (add/merge)
-
target.getFrameworkProperties().putAll(source.getFrameworkProperties());
-
- // requirements (add)
- for(final Requirement req : source.getRequirements()) {
- target.getRequirements().add(req);
- }
-
- // capabilities (add)
- for(final Capability cap : source.getCapabilities()) {
- target.getCapabilities().add(cap);
- }
-
- // extensions (add/merge)
- for(final Extension ext : source.getExtensions()) {
- boolean found = false;
- for(final Extension current : target.getExtensions()) {
- if ( current.getName().equals(ext.getName()) ) {
- found = true;
- if ( current.getType() != ext.getType() ) {
- throw new IllegalStateException("Found different types
for extension " + current.getName()
- + " : " + current.getType() + " and " + ext.getType());
- }
- switch ( current.getType() ) {
- case TEXT : // simply append
- current.setText(current.getText() + "\n" +
ext.getText());
- break;
- case JSON : final JsonStructure struct1;
- try ( final StringReader reader = new
StringReader(current.getJSON()) ) {
- struct1 =
Json.createReader(reader).read();
- }
- final JsonStructure struct2;
- try ( final StringReader reader = new
StringReader(ext.getJSON()) ) {
- struct2 =
Json.createReader(reader).read();
- }
-
- if ( struct1.getValueType() !=
struct2.getValueType() ) {
- throw new IllegalStateException("Found
different JSON types for extension " + current.getName()
- + " : " + struct1.getValueType() + "
and " + struct2.getValueType());
- }
- if ( struct1.getValueType() ==
ValueType.ARRAY ) {
- // array is append
- final JsonArray a1 =
(JsonArray)struct1;
- final JsonArray a2 =
(JsonArray)struct2;
- for(final JsonValue val : a2) {
- a1.add(val);
- }
- } else {
- // object is merge
- merge((JsonObject)struct1,
(JsonObject)struct2);
- }
- break;
-
- case ARTIFACTS : for(final Artifact a :
ext.getArtifacts()) {
- // remove same artifact - latest
version wins (not highest)
- for(final Artifact targetArtifact
: current.getArtifacts()) {
- if (
targetArtifact.getId().isSame(a.getId()) ) {
-
current.getArtifacts().remove(targetArtifact);
- break;
- }
- }
- current.getArtifacts().add(a);
- }
- break;
-
- }
- }
- }
- if ( !found ) {
- target.getExtensions().add(ext);
- }
- }
- }
-
- private static void merge(final JsonObject obj1, final JsonObject obj2) {
- for(final Map.Entry<String, JsonValue> entry : obj2.entrySet()) {
- if ( !obj1.containsKey(entry.getKey()) ) {
- obj1.put(entry.getKey(), entry.getValue());
- } else {
- final JsonValue oldValue = obj1.get(entry.getKey());
- if ( oldValue.getValueType() !=
entry.getValue().getValueType() ) {
- // new type wins
- obj1.put(entry.getKey(), entry.getValue());
- } else if ( oldValue.getValueType() == ValueType.ARRAY ) {
- final JsonArray a1 = (JsonArray)oldValue;
- final JsonArray a2 = (JsonArray)entry.getValue();
- for(final JsonValue val : a2) {
- a1.add(val);
- }
-
- } else if ( oldValue.getValueType() == ValueType.OBJECT ) {
- merge((JsonObject)oldValue, (JsonObject)entry.getValue());
- } else {
- obj1.put(entry.getKey(), entry.getValue());
- }
- }
- }
+ BuilderUtil.mergeBundles(target.getBundles(), source.getBundles(),
BuilderUtil.ArtifactMerge.LATEST);
+ BuilderUtil.mergeConfigurations(target.getConfigurations(),
source.getConfigurations());
+ BuilderUtil.mergeFrameworkProperties(target.getFrameworkProperties(),
source.getFrameworkProperties());
+ BuilderUtil.mergeRequirements(target.getRequirements(),
source.getRequirements());
+ BuilderUtil.mergeCapabilities(target.getCapabilities(),
source.getCapabilities());
+ BuilderUtil.mergeExtensions(target.getExtensions(),
source.getExtensions(), BuilderUtil.ArtifactMerge.LATEST);
}
private static void include(final Feature base, final Include i) {