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) {


Reply via email to