Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 02471200D35 for ; Tue, 7 Nov 2017 10:57:08 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 00BD3160C05; Tue, 7 Nov 2017 09:57:08 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 0D2CC160C24 for ; Tue, 7 Nov 2017 10:57:03 +0100 (CET) Received: (qmail 15333 invoked by uid 500); 7 Nov 2017 09:57:03 -0000 Mailing-List: contact commits-help@sling.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@sling.apache.org Delivered-To: mailing list commits@sling.apache.org Received: (qmail 15108 invoked by uid 99); 7 Nov 2017 09:57:03 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 07 Nov 2017 09:57:03 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id 7663287AD7; Tue, 7 Nov 2017 09:57:02 +0000 (UTC) Date: Tue, 07 Nov 2017 09:58:19 +0000 To: "commits@sling.apache.org" Subject: [sling-org-apache-sling-provisioning-model] 04/11: SLING-5172 : Provide support for custom sections in the provisioning model MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit From: rombert@apache.org In-Reply-To: <151004861629.6692.9831658499042110389@gitbox.apache.org> References: <151004861629.6692.9831658499042110389@gitbox.apache.org> X-Git-Host: gitbox.apache.org X-Git-Repo: sling-org-apache-sling-provisioning-model X-Git-Refname: refs/tags/org.apache.sling.provisioning.model-1.4.0 X-Git-Reftype: annotated tag X-Git-Rev: d0779ce506dbf28cc2b56539f56243b185fa74b2 X-Git-NotificationType: diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated Message-Id: <20171107095702.7663287AD7@gitbox.apache.org> archived-at: Tue, 07 Nov 2017 09:57:08 -0000 This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.provisioning.model-1.4.0 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-provisioning-model.git commit d0779ce506dbf28cc2b56539f56243b185fa74b2 Author: Carsten Ziegeler AuthorDate: Tue Oct 20 14:00:14 2015 +0000 SLING-5172 : Provide support for custom sections in the provisioning model git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/tooling/support/provisioning-model@1709592 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/sling/provisioning/model/Feature.java | 48 +++++++++++- .../sling/provisioning/model/ModelProcessor.java | 13 ++-- .../sling/provisioning/model/ModelUtility.java | 35 +++++---- .../apache/sling/provisioning/model/Section.java | 87 ++++++++++++++++++++++ .../sling/provisioning/model/io/ModelReader.java | 39 +++++++++- .../sling/provisioning/model/io/ModelWriter.java | 18 +++++ .../apache/sling/provisioning/model/io/IOTest.java | 10 +++ src/test/resources/additional.txt | 35 +++++++++ 8 files changed, 259 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/apache/sling/provisioning/model/Feature.java b/src/main/java/org/apache/sling/provisioning/model/Feature.java index 1d892ec..c78cb3e 100644 --- a/src/main/java/org/apache/sling/provisioning/model/Feature.java +++ b/src/main/java/org/apache/sling/provisioning/model/Feature.java @@ -32,6 +32,10 @@ public class Feature extends Commentable implements Comparable { + /** + * The feature type + * @since 1.4.0 + */ public enum Type { PLAIN("plain"), SUBSYSTEM_FEATURE("osgi.subsystem.feature"), @@ -72,6 +76,9 @@ public class Feature /** Feature name. */ private final String name; + /** Additional sections. */ + private final List
additionalSections = new ArrayList
(); + /** * Construct a new feature. * @param name The feature name @@ -144,12 +151,48 @@ public class Feature return result; } + /** + * Get the feature type. + * @return The feature type. + * @since 1.4.0 + */ public Type getType() { return type; } - public void setType(Type t) { - type = t; + /** + * Set the feature type. + * @param t The new type + * @since 1.4.0 + */ + public void setType(final Type t) { + type = ( t == null ? Type.PLAIN : t); + } + + /** + * Get all additional sections + * @return The list of additional sections. It might be empty. + * @since 1.4.0 + */ + public List
getAdditionalSections() { + return this.additionalSections; + } + + /** + * Get all sections with the given name. + * @param name The section name. + * @return The list of sections. The list might be empty. + * @since 1.4.0 + */ + public List
getAdditionalSections(final String name) { + final List
result = new ArrayList
(); + + for(final Section s : this.additionalSections) { + if ( name.equals(s.getName()) ) { + result.add(s); + } + } + return result; } @Override @@ -171,6 +214,7 @@ public class Feature return "Feature [runModes=" + runModes + ", variables=" + variables + ", name=" + name + ( type != Type.PLAIN ? ", type=" + type : "" ) + + ( additionalSections.isEmpty() ? "" : ", additionalSections=" + this.additionalSections) + ( this.getLocation() != null ? ", location=" + this.getLocation() : "") + "]"; } diff --git a/src/main/java/org/apache/sling/provisioning/model/ModelProcessor.java b/src/main/java/org/apache/sling/provisioning/model/ModelProcessor.java index ad4fcfc..58cad6d 100644 --- a/src/main/java/org/apache/sling/provisioning/model/ModelProcessor.java +++ b/src/main/java/org/apache/sling/provisioning/model/ModelProcessor.java @@ -23,10 +23,10 @@ import java.util.Enumeration; /** * Allows to process a value. A new value is created and for each part in the model a process * method is called. Subclasses can overwrite those methods to inject specific behavior. - * The processor itself does not change anything in the model. + * The processor itself does not change anything in the model. */ class ModelProcessor { - + /** * Creates a copy of the model and calls a process method for each part found in the model. * This allows to modify the parts content (e.g. replace variables), but not to add or remove parts. @@ -42,6 +42,7 @@ class ModelProcessor { newFeature.setType(feature.getType()); newFeature.setComment(feature.getComment()); newFeature.setLocation(feature.getLocation()); + newFeature.getAdditionalSections().addAll(feature.getAdditionalSections()); newFeature.getVariables().setComment(feature.getVariables().getComment()); newFeature.getVariables().setLocation(feature.getVariables().getLocation()); @@ -86,15 +87,15 @@ class ModelProcessor { } return result; } - + protected KeyValueMap processVariables(KeyValueMap variables, Feature newFeature) { return variables; } - + protected Artifact processArtifact(Artifact artifact, Feature newFeature, RunMode newRunMode) { return artifact; } - + protected Configuration processConfiguration(Configuration config, Feature newFeature, RunMode newRunMode) { return config; } @@ -102,5 +103,5 @@ class ModelProcessor { protected KeyValueMap processSettings(KeyValueMap settings, Feature newFeature, RunMode newRunMode) { return settings; } - + } diff --git a/src/main/java/org/apache/sling/provisioning/model/ModelUtility.java b/src/main/java/org/apache/sling/provisioning/model/ModelUtility.java index 806975d..3a30ab9 100644 --- a/src/main/java/org/apache/sling/provisioning/model/ModelUtility.java +++ b/src/main/java/org/apache/sling/provisioning/model/ModelUtility.java @@ -53,6 +53,9 @@ public abstract class ModelUtility { final Feature baseFeature = base.getOrCreateFeature(feature.getName()); baseFeature.setType(feature.getType()); + // additional sections + baseFeature.getAdditionalSections().addAll(feature.getAdditionalSections()); + // variables baseFeature.getVariables().putAll(feature.getVariables()); @@ -277,33 +280,33 @@ public abstract class ModelUtility { */ String resolve(final Artifact artifact); } - + /** * Parameter builder class for {@link ModelUtility#getEffectiveModel(Model, ResolverOptions)} method. */ public static final class ResolverOptions { - + private VariableResolver variableResolver; private ArtifactVersionResolver artifactVersionResolver; - + public VariableResolver getVariableResolver() { return variableResolver; } - + public ResolverOptions variableResolver(VariableResolver variableResolver) { this.variableResolver = variableResolver; return this; } - + public ArtifactVersionResolver getArtifactVersionResolver() { return artifactVersionResolver; } - + public ResolverOptions artifactVersionResolver(ArtifactVersionResolver dependencyVersionResolver) { this.artifactVersionResolver = dependencyVersionResolver; return this; } - + } /** @@ -318,7 +321,7 @@ public abstract class ModelUtility { public static Model getEffectiveModel(final Model model, final VariableResolver resolver) { return getEffectiveModel(model, new ResolverOptions().variableResolver(resolver)); } - + /** * Replace all variables in the model and return a new model with the replaced values. * @param model The base model. @@ -329,7 +332,7 @@ public abstract class ModelUtility { public static Model getEffectiveModel(final Model model) { return getEffectiveModel(model, new ResolverOptions()); } - + /** * Replace all variables in the model and return a new model with the replaced values. * @param model The base model. @@ -417,7 +420,7 @@ public abstract class ModelUtility { } return errors; } - + /** * Applies a set of variables to the given model. * All variables that are referenced anywhere within the model are detected and passed to the given variable resolver. @@ -430,7 +433,7 @@ public abstract class ModelUtility { * @since 1.3 */ public static Model applyVariables(final Model model, final VariableResolver resolver) { - + // define delegating resolver that collects all variable names and value per feature final Map> collectedVars = new HashMap>(); VariableResolver variableCollector = new VariableResolver() { @@ -448,10 +451,10 @@ public abstract class ModelUtility { return value; } }; - + // use effective model processor to collect variables, but drop the resulting model new EffectiveModelProcessor(new ResolverOptions().variableResolver(variableCollector)).process(model); - + // define a processor that updates the "variables" sections in the features ModelProcessor variablesUpdater = new ModelProcessor() { @Override @@ -466,7 +469,7 @@ public abstract class ModelUtility { return newVariables; } }; - + // return model with replaced "variables" sections return variablesUpdater.process(model); } @@ -482,7 +485,7 @@ public abstract class ModelUtility { * @since 1.3 */ public static Model applyArtifactVersions(final Model model, final ArtifactVersionResolver resolver) { - + // define a processor that updates the versions of artifacts ModelProcessor versionUpdater = new ModelProcessor() { @Override @@ -501,7 +504,7 @@ public abstract class ModelUtility { artifact.getType()); } }; - + // return model with updated version artifacts return versionUpdater.process(model); } diff --git a/src/main/java/org/apache/sling/provisioning/model/Section.java b/src/main/java/org/apache/sling/provisioning/model/Section.java new file mode 100644 index 0000000..5c4ce38 --- /dev/null +++ b/src/main/java/org/apache/sling/provisioning/model/Section.java @@ -0,0 +1,87 @@ +/* + * 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.provisioning.model; + +import java.util.HashMap; +import java.util.Map; + + +/** + * An additional section in the provisioning model. + * @since 1.4 + */ +public class Section + extends Commentable { + + /** The section name. */ + private final String name; + + /** Attributes. */ + private final Map attributes = new HashMap(); + + /** Contents. */ + private volatile String contents; + + /** + * Construct a new feature. + * @param name The feature name + */ + public Section(final String name) { + this.name = name; + } + + /** + * Get the name of the section. + * @return The name or {@code null} for an anonymous feature. + */ + public String getName() { + return this.name; + } + + /** + * Get all attributes + * @return The map of attributes. + */ + public Map getAttributes() { + return this.attributes; + } + + /** + * Get the contents of the section. + * @return The contents or {@code null}. + */ + public String getContents() { + return contents; + } + + /** + * Set the contents of the section. + * @param contents The new contents. + */ + public void setContents(final String contents) { + this.contents = contents; + } + + @Override + public String toString() { + return "Section [name=" + name + + ( attributes.isEmpty() ? "": ", attributes=" + attributes ) + + ( contents == null ? "" : ", contents=" + contents) + + ( this.getLocation() != null ? ", location=" + this.getLocation() : "") + + "]"; + } +} diff --git a/src/main/java/org/apache/sling/provisioning/model/io/ModelReader.java b/src/main/java/org/apache/sling/provisioning/model/io/ModelReader.java index ec37e48..21ef564 100644 --- a/src/main/java/org/apache/sling/provisioning/model/io/ModelReader.java +++ b/src/main/java/org/apache/sling/provisioning/model/io/ModelReader.java @@ -31,6 +31,7 @@ import org.apache.sling.provisioning.model.Feature; import org.apache.sling.provisioning.model.Model; import org.apache.sling.provisioning.model.ModelConstants; import org.apache.sling.provisioning.model.RunMode; +import org.apache.sling.provisioning.model.Section; /** * This class offers a method to read a model using a {@code Reader} instance. @@ -44,7 +45,8 @@ public class ModelReader { ARTIFACTS("artifacts", new String[] {"runModes", "startLevel"}), SETTINGS("settings", new String[] {"runModes"}), CONFIGURATIONS("configurations", new String[] {"runModes"}), - CONFIG(null, null); + CONFIG(null, null), + ADDITIONAL(null, null); public final String name; @@ -79,6 +81,8 @@ public class ModelReader { private ArtifactGroup artifactGroup; private Configuration config; + private Section additionalSection; + private String comment; private StringBuilder configBuilder; @@ -109,6 +113,14 @@ public class ModelReader { // ignore empty line if ( line.isEmpty() ) { + if ( this.mode == CATEGORY.ADDITIONAL ) { + if ( this.additionalSection.getContents() == null ) { + this.additionalSection.setContents(line); + } else { + this.additionalSection.setContents(this.additionalSection.getContents() + '\n' + line); + } + continue; + } checkConfig(); continue; } @@ -121,6 +133,14 @@ public class ModelReader { continue; } + if ( this.mode == CATEGORY.ADDITIONAL ) { + if ( this.additionalSection.getContents() == null ) { + this.additionalSection.setContents(line); + } else { + this.additionalSection.setContents(this.additionalSection.getContents() + '\n' + line); + } + continue; + } final String c = line.substring(1).trim(); if ( comment == null ) { comment = c; @@ -138,6 +158,7 @@ public class ModelReader { } if ( line.startsWith("[") ) { + additionalSection = null; if ( !line.endsWith("]") ) { throw new IOException(exceptionPrefix + "Illegal category definition in line " + this.lineNumberReader.getLineNumber() + ": " + line); } @@ -154,7 +175,8 @@ public class ModelReader { } } if ( found == null ) { - throw new IOException(exceptionPrefix + "Unknown category in line " + this.lineNumberReader.getLineNumber() + ": " + line); + // additional section + found = CATEGORY.ADDITIONAL; } this.mode = found; Map parameters = Collections.emptyMap(); @@ -207,6 +229,13 @@ public class ModelReader { checkRunMode(parameters); this.init(this.runMode.getConfigurations()); break; + case ADDITIONAL: checkFeature(); + this.runMode = null; + this.artifactGroup = null; + this.additionalSection = new Section(category); + this.init(this.additionalSection); + this.feature.getAdditionalSections().add(this.additionalSection); + this.additionalSection.getAttributes().putAll(parameters); } } else { switch ( this.mode ) { @@ -288,6 +317,12 @@ public class ModelReader { case CONFIG : configBuilder.append(line); configBuilder.append('\n'); break; + case ADDITIONAL : if ( this.additionalSection.getContents() == null ) { + this.additionalSection.setContents(line); + } else { + this.additionalSection.setContents(this.additionalSection.getContents() + '\n' + line); + } + break; } } diff --git a/src/main/java/org/apache/sling/provisioning/model/io/ModelWriter.java b/src/main/java/org/apache/sling/provisioning/model/io/ModelWriter.java index d1fe473..e6160b3 100644 --- a/src/main/java/org/apache/sling/provisioning/model/io/ModelWriter.java +++ b/src/main/java/org/apache/sling/provisioning/model/io/ModelWriter.java @@ -33,6 +33,7 @@ import org.apache.sling.provisioning.model.Feature; import org.apache.sling.provisioning.model.Model; import org.apache.sling.provisioning.model.ModelConstants; import org.apache.sling.provisioning.model.RunMode; +import org.apache.sling.provisioning.model.Section; /** * Simple writer for the a model @@ -236,6 +237,23 @@ public class ModelWriter { } } } + + // additional sections + for(final Section section : feature.getAdditionalSections()) { + pw.print(" ["); + pw.print(section.getName()); + for(final Map.Entry entry : section.getAttributes().entrySet()) { + pw.print(' '); + pw.print(entry.getKey()); + pw.print('='); + pw.print(entry.getValue()); + } + pw.println("]"); + if ( section.getContents() != null ) { + pw.println(section.getContents()); + } + pw.println(); + } } } } diff --git a/src/test/java/org/apache/sling/provisioning/model/io/IOTest.java b/src/test/java/org/apache/sling/provisioning/model/io/IOTest.java index 5fa6a1e..bcfe275 100644 --- a/src/test/java/org/apache/sling/provisioning/model/io/IOTest.java +++ b/src/test/java/org/apache/sling/provisioning/model/io/IOTest.java @@ -18,6 +18,7 @@ package org.apache.sling.provisioning.model.io; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import java.io.StringReader; @@ -27,6 +28,7 @@ import java.util.List; import java.util.Map; import org.apache.sling.provisioning.model.Configuration; +import org.apache.sling.provisioning.model.Feature; import org.apache.sling.provisioning.model.Model; import org.apache.sling.provisioning.model.ModelUtility; import org.apache.sling.provisioning.model.Traceable; @@ -113,4 +115,12 @@ public class IOTest { assertEquals("C", cfgC.getProperties().get("name")); assertArrayEquals(new Integer[] {1,2,3}, (Integer[])cfgC.getProperties().get("array")); } + + @Test public void testAddition() throws Exception { + final Model model = U.readCompleteTestModel(new String[] {"additional.txt"}); + final Feature f = model.getFeature("main"); + assertNotNull(f); + assertEquals(1, f.getAdditionalSections().size()); + assertEquals(1, f.getAdditionalSections("additional").size()); + } } diff --git a/src/test/resources/additional.txt b/src/test/resources/additional.txt new file mode 100644 index 0000000..b9b1524 --- /dev/null +++ b/src/test/resources/additional.txt @@ -0,0 +1,35 @@ +# +# 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. +# +[feature name=main] + +[variables] + ws.version=1.0.2-from-main + +[artifacts] + commons-io/commons-io/1.4/jar + +[additional stuff=free] + # Hello + world + + Hello + +[configurations] + org.apache.test.A + name="A" -- To stop receiving notification emails like this one, please contact "commits@sling.apache.org" .