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 2017/06/02 14:02:13 UTC
svn commit: r1797391 - in /sling/whiteboard/cziegeler:
feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/
feature-support/src/main/java/org/apache/sling/feature/support/
feature-support/src/main/java/org/apache/sling/feature/support...
Author: cziegeler
Date: Fri Jun 2 14:02:13 2017
New Revision: 1797391
URL: http://svn.apache.org/viewvc?rev=1797391&view=rev
Log:
Move common file handling to support bundle
Added:
sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/FeatureUtil.java (with props)
sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/package-info.java (with props)
sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/spi/package-info.java (with props)
Modified:
sling/whiteboard/cziegeler/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
sling/whiteboard/cziegeler/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java
Modified: sling/whiteboard/cziegeler/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java?rev=1797391&r1=1797390&r2=1797391&view=diff
==============================================================================
--- sling/whiteboard/cziegeler/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java (original)
+++ sling/whiteboard/cziegeler/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java Fri Jun 2 14:02:13 2017
@@ -17,34 +17,25 @@
package org.apache.sling.feature.launcher.impl;
import java.io.File;
-import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.List;
import java.util.Map;
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.ExtensionType;
-import org.apache.sling.feature.Feature;
import org.apache.sling.feature.json.ApplicationJSONWriter;
-import org.apache.sling.feature.json.FeatureJSONReader;
import org.apache.sling.feature.launcher.impl.LauncherConfig.StartupMode;
-import org.apache.sling.feature.process.ApplicationBuilder;
-import org.apache.sling.feature.process.FeatureProvider;
import org.apache.sling.feature.support.ArtifactHandler;
import org.apache.sling.feature.support.ArtifactManager;
+import org.apache.sling.feature.support.FeatureUtil;
import org.apache.sling.feature.support.Logger;
public class FeatureProcessor {
- // Framework extension
- private static final String EXT_NAME = "framework";
-
/**
* Initialize the launcher
* Read the features and prepare the application
@@ -52,73 +43,12 @@ public class FeatureProcessor {
* @param artifactManager The artifact manager
*/
public static Application createApplication(final LauncherConfig config,
- final ArtifactManager artifactManager) {
- final List<Feature> features = new ArrayList<>();
- try {
- for(String initFile : config.getFeatureFiles()) {
- try {
- final Feature f = getFeature(config, initFile, artifactManager);
- features.add(f);
- } catch ( final IOException iae) {
- Logger.LOG.error("Unable to read feature {0} : {1}", iae, initFile, iae.getMessage());
- System.exit(1);
- }
- }
- } catch ( final IOException iae) {
- Logger.LOG.error("Unable to read feature : {0}", iae, iae.getMessage());
- System.exit(1);
- }
-
- if ( features.isEmpty() ) {
- Logger.LOG.error("No features defined.");
- System.exit(1);
- }
-
- final Application app = ApplicationBuilder.assemble(new FeatureProvider() {
-
- @Override
- public Feature provide(final ArtifactId id) {
- try {
- final ArtifactHandler handler = artifactManager.getArtifactHandler("mvn:" + id.toMvnPath());
- try (final FileReader r = new FileReader(handler.getFile())) {
- final Feature f = FeatureJSONReader.read(r, handler.getUrl());
- return f;
- }
-
- } catch (final IOException e) {
- // ignore
- }
- return null;
- }
- }, features.toArray(new Feature[features.size()]));
-
- // search for framework extension
- Extension fwk = null;
- for(final Extension e : app.getExtensions()) {
- if ( e.getName().equals(EXT_NAME) ) {
- fwk = e;
- }
- }
- if ( fwk != null ) {
- if ( fwk.getType() != ExtensionType.ARTIFACTS ) {
- Logger.LOG.error("Extension " + EXT_NAME + " is of wrong type: " + fwk.getType());
- System.exit(1);
- }
- if ( fwk.getArtifacts().size() != 1 ) {
- Logger.LOG.error("Extension " + EXT_NAME + " must have exactly one artifact: " + fwk.getArtifacts().size());
- System.exit(1);
- }
- app.setFramework(fwk.getArtifacts().get(0).getId());
- app.getExtensions().remove(fwk);
- } else {
- // use hard coded Apache Felix
- app.setFramework(new ArtifactId("org.apache.felix",
- "org.apache.felix.framework",
- "5.6.4", null, null));
- }
+ final ArtifactManager artifactManager) throws IOException {
+ final Application app = FeatureUtil.assembleApplication(FeatureUtil.getFeatureFiles(config.getHomeDirectory(), config.getFeatureFiles()),
+ artifactManager);
// write application back
- final File file = new File(config.getHomeDirectory(), "resources" + File.separatorChar + "provisioning" + File.separatorChar + "feature.txt");
+ final File file = new File(config.getHomeDirectory(), "resources" + File.separatorChar + "provisioning" + File.separatorChar + "application.json");
file.getParentFile().mkdirs();
try (final FileWriter writer = new FileWriter(file)) {
@@ -132,33 +62,6 @@ public class FeatureProcessor {
}
/**
- * Read the feature
- * @param config The launcher configuration
- * @param name The feature file
- * @param artifactManager The artifact manager to read the model
- * @return The read feature
- * @throws IOException If reading fails
- */
- private static Feature getFeature(final LauncherConfig config,
- final String file,
- final ArtifactManager artifactManager) throws IOException {
- ArtifactHandler featureArtifact = null;
- try {
- featureArtifact = artifactManager.getArtifactHandler(file);
- } catch ( final IOException use) {
- Logger.LOG.error("Invalid feature url {0}", file);
- Logger.LOG.debug("Exception while getting artifact " + file, use);
- System.exit(1);
- }
- Logger.LOG.log("- reading feature {0}", featureArtifact.getUrl());
-
- try (final FileReader r = new FileReader(featureArtifact.getFile())) {
- final Feature f = FeatureJSONReader.read(r, featureArtifact.getUrl());
- return f;
- }
- }
-
- /**
* Prepare the launcher
* - add all bundles to the bundle map of the installation object
* - add all other artifacts to the install directory (only if startup mode is INSTALL)
Modified: sling/whiteboard/cziegeler/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java?rev=1797391&r1=1797390&r2=1797391&view=diff
==============================================================================
--- sling/whiteboard/cziegeler/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java (original)
+++ sling/whiteboard/cziegeler/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java Fri Jun 2 14:02:13 2017
@@ -18,11 +18,6 @@ package org.apache.sling.feature.launche
import java.io.File;
import java.io.IOException;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
import org.apache.sling.feature.support.ArtifactManagerConfig;
import org.apache.sling.feature.support.spi.ArtifactProviderContext;
@@ -34,33 +29,6 @@ public class LauncherConfig
extends ArtifactManagerConfig
implements ArtifactProviderContext {
- public static final Comparator<String> FEATURE_PATH_COMP = new Comparator<String>() {
-
- @Override
- public int compare(final String o1, final String o2) {
- // windows path conversion
- final String key1 = o1.replace(File.separatorChar, '/');
- final String key2 = o2.replace(File.separatorChar, '/');
-
- final int lastSlash1 = key1.lastIndexOf('/');
- final int lastSlash2 = key2.lastIndexOf('/');
- if ( lastSlash1 == -1 || lastSlash2 == -1 ) {
- return o1.compareTo(o2);
- }
- final String path1 = key1.substring(0, lastSlash1 + 1);
- final String path2 = key2.substring(0, lastSlash2 + 1);
- if ( path1.equals(path2) ) {
- return o1.compareTo(o2);
- }
- if ( path1.startsWith(path2) ) {
- return 1;
- } else if ( path2.startsWith(path1) ) {
- return -1;
- }
- return o1.compareTo(o2);
- }
- };
-
public enum StartupMode {
INSTALLER,
PURE
@@ -96,89 +64,13 @@ public class LauncherConfig
}
}
- private void processDir(final List<String> paths, final File dir)
- throws IOException {
- for(final File f : dir.listFiles()) {
- if ( f.isFile() && !f.getName().startsWith(".")) {
- // check if file is a reference
- if ( f.getName().endsWith(".ref") ) {
- final List<String> lines = Files.readAllLines(f.toPath());
- for(String line : lines) {
- line = line.trim();
- if ( !line.isEmpty() && !line.startsWith("#") ) {
- paths.add(line);
- }
- }
- } else {
- paths.add(f.getAbsolutePath());
- }
- }
- }
- }
-
- private void processFile(final List<String> paths, final File f)
- throws IOException {
- if ( f.getName().endsWith(".ref") ) {
- final List<String> lines = Files.readAllLines(f.toPath());
- for(String line : lines) {
- line = line.trim();
- if ( !line.isEmpty() && !line.startsWith("#") ) {
- if ( line.indexOf(':') == -1 ) {
- paths.add(new File(line).getAbsolutePath());
- } else {
- paths.add(line);
- }
- }
- }
- } else {
- paths.add(f.getAbsolutePath());
- }
- }
-
/**
* Get the list of feature files.
* @return The array of names.
* @throws IOException
*/
- public String[] getFeatureFiles() throws IOException {
- if ( this.featureFiles == null ) {
- // Default value - check feature directory otherwise features file
- final File dir = new File(getHomeDirectory(), "features");
- if ( dir.exists() && dir.isDirectory() ) {
- this.featureFiles = new String[] {"features"};
- } else {
- this.featureFiles = new String[] {new File("feature.txt").getAbsolutePath()};
- }
- }
- final List<String> paths = new ArrayList<>();
- for(final String name : this.featureFiles) {
- // check for absolute
- if ( name.indexOf(':') > 0 ) {
- paths.add(name);
- } else {
- // relative
- final File f = new File(name);
- if ( f.exists() ) {
- if ( f.isFile() ) {
- this.processFile(paths, f);
- } else {
- this.processDir(paths, f);
- }
- } else if ( !f.exists() ) {
- final File check = new File(getHomeDirectory(), "features" + File.separatorChar + name);
- if ( check.exists() && !check.getName().startsWith(".") ) {
- if ( check.isFile() ) {
- this.processFile(paths, check);
- } else {
- this.processDir(paths, check);
- }
- }
- }
- }
- }
-
- Collections.sort(paths, FEATURE_PATH_COMP);
- return paths.toArray(new String[paths.size()]);
+ public String[] getFeatureFiles() {
+ return this.featureFiles;
}
Added: sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/FeatureUtil.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/FeatureUtil.java?rev=1797391&view=auto
==============================================================================
--- sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/FeatureUtil.java (added)
+++ sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/FeatureUtil.java Fri Jun 2 14:02:13 2017
@@ -0,0 +1,283 @@
+/*
+ * 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.support;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.sling.feature.Application;
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.ExtensionType;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.json.FeatureJSONReader;
+import org.apache.sling.feature.process.ApplicationBuilder;
+import org.apache.sling.feature.process.FeatureProvider;
+
+public class FeatureUtil {
+
+ /**
+ * Get an artifact id for the Apache Felix framework
+ * @param version The version to use or {@code null} for the default version
+ * @return The artifact id
+ * @throws IllegalArgumentException If the provided version is invalid
+ */
+ public static ArtifactId getFelixFrameworkId(final String version) {
+ return new ArtifactId("org.apache.felix",
+ "org.apache.felix.framework",
+ version != null ? version : "5.6.4", null, null);
+ }
+
+ private static final Comparator<String> FEATURE_PATH_COMP = new Comparator<String>() {
+
+ @Override
+ public int compare(final String o1, final String o2) {
+ // windows path conversion
+ final String key1 = o1.replace(File.separatorChar, '/');
+ final String key2 = o2.replace(File.separatorChar, '/');
+
+ final int lastSlash1 = key1.lastIndexOf('/');
+ final int lastSlash2 = key2.lastIndexOf('/');
+ if ( lastSlash1 == -1 || lastSlash2 == -1 ) {
+ return o1.compareTo(o2);
+ }
+ final String path1 = key1.substring(0, lastSlash1 + 1);
+ final String path2 = key2.substring(0, lastSlash2 + 1);
+ if ( path1.equals(path2) ) {
+ return o1.compareTo(o2);
+ }
+ if ( path1.startsWith(path2) ) {
+ return 1;
+ } else if ( path2.startsWith(path1) ) {
+ return -1;
+ }
+ return o1.compareTo(o2);
+ }
+ };
+
+ private static void processDir(final List<String> paths, final File dir)
+ throws IOException {
+ for(final File f : dir.listFiles()) {
+ if ( f.isFile() && !f.getName().startsWith(".")) {
+ // check if file is a reference
+ if ( f.getName().endsWith(".ref") ) {
+ final List<String> lines = Files.readAllLines(f.toPath());
+ for(String line : lines) {
+ line = line.trim();
+ if ( !line.isEmpty() && !line.startsWith("#") ) {
+ paths.add(line);
+ }
+ }
+ } else if ( f.getName().endsWith(".json")) {
+ paths.add(f.getAbsolutePath());
+ }
+ }
+ }
+ }
+
+ private static void processFile(final List<String> paths, final File f)
+ throws IOException {
+ if ( f.getName().endsWith(".ref") ) {
+ final List<String> lines = Files.readAllLines(f.toPath());
+ for(String line : lines) {
+ line = line.trim();
+ if ( !line.isEmpty() && !line.startsWith("#") ) {
+ if ( line.indexOf(':') == -1 ) {
+ paths.add(new File(line).getAbsolutePath());
+ } else {
+ paths.add(line);
+ }
+ }
+ }
+ } else {
+ paths.add(f.getAbsolutePath());
+ }
+ }
+
+ /**
+ * Get the list of feature files.
+ * If the provided list of files is {@code null} or an empty array, the default is used.
+ * The default checks for the following places, the first one found is used. If none is
+ * found an empty list is returned.
+ * <ol>
+ * <li>A directory named {@code feature} in the current directory
+ * <li>A file named {@code features.json} in the current directory
+ * <li>A directory named {@code feature} in the home directory
+ * <li>A file named {@code features.json} in the home directory
+ * </ol>
+ *
+ * The list of files is processed one after the other. If it is relative, it is
+ * first tried to be resolved against the current directory and then against the
+ * home directory.
+ * If an entry denotes a directory, all children ending in {@code .json} or {@code .ref} of that directory are read.
+ * If a file ends in {@code .ref} the contents is read and every line not starting with the
+ * hash sign is considered a reference to a feature artifact.
+ *
+ * @param homeDirectory If relative files should be resolved, this is the directory to use
+ * @param files Optional list of files. If none is provided, a default is used.
+ * @return The list of files.
+ * @throws IOException If an error occurs.
+ */
+ public static List<String> getFeatureFiles(final File homeDirectory, final String... files) throws IOException {
+ String[] featureFiles = files;
+ if ( featureFiles == null || files.length == 0 ) {
+ // Default value - check feature directory otherwise features file
+ final File[] candidates = new File[] {
+ new File("features"),
+ new File("features.json"),
+ new File(homeDirectory, "features"),
+ new File(homeDirectory, "features.json")
+ };
+ File f = null;
+ for(final File c : candidates) {
+ f = c;
+ if ( f.exists() ) {
+ break;
+ }
+ }
+ featureFiles = new String[] {f.getAbsolutePath()};
+ }
+ final List<String> paths = new ArrayList<>();
+ for(final String name : featureFiles) {
+ // check for absolute
+ if ( name.indexOf(':') > 1 ) {
+ paths.add(name);
+ } else {
+ // file or relative
+ final File[] candidates = {
+ new File(name),
+ new File(homeDirectory, name),
+ new File("features" + File.separatorChar + name),
+ new File(homeDirectory, "features" + File.separatorChar + name)
+ };
+ File f = null;
+ for(final File c : candidates) {
+ f = c;
+ if ( c.isAbsolute() || c.exists() ) {
+ break;
+ }
+ }
+
+ if ( f.exists() ) {
+ if ( f.isFile() ) {
+ processFile(paths, f);
+ } else {
+ processDir(paths, f);
+ }
+ } else {
+ // we simply add the path and fail later on
+ paths.add(f.getAbsolutePath());
+ }
+ }
+ }
+
+ Collections.sort(paths, FEATURE_PATH_COMP);
+ return paths;
+ }
+
+ // Framework extension
+ private static final String EXT_NAME = "framework";
+
+ /**
+ * Assemble an application based on the given files.
+ *
+ * Read the features and assemble the application
+ * @param featureFiles The feature files.
+ * @param artifactManager The artifact manager
+ * @throws IOException If a feature can't be read or no feature is found.
+ * @see #getFeatureFiles(File, String...)
+ */
+ public static Application assembleApplication(final List<String> featureFiles,
+ final ArtifactManager artifactManager)
+ throws IOException {
+ final List<Feature> features = new ArrayList<>();
+ for(final String initFile : featureFiles) {
+ final Feature f = getFeature(initFile, artifactManager);
+ features.add(f);
+ }
+
+ if ( features.isEmpty() ) {
+ throw new IOException("No features found.");
+ }
+
+ final Application app = ApplicationBuilder.assemble(new FeatureProvider() {
+
+ @Override
+ public Feature provide(final ArtifactId id) {
+ try {
+ final ArtifactHandler handler = artifactManager.getArtifactHandler("mvn:" + id.toMvnPath());
+ try (final FileReader r = new FileReader(handler.getFile())) {
+ final Feature f = FeatureJSONReader.read(r, handler.getUrl());
+ return f;
+ }
+
+ } catch (final IOException e) {
+ // ignore
+ }
+ return null;
+ }
+ }, features.toArray(new Feature[features.size()]));
+
+ // search for framework extension
+ Extension fwk = null;
+ for(final Extension e : app.getExtensions()) {
+ if ( e.getName().equals(EXT_NAME) ) {
+ fwk = e;
+ }
+ }
+ if ( fwk != null ) {
+ if ( fwk.getType() != ExtensionType.ARTIFACTS ) {
+ throw new IOException("Extension " + EXT_NAME + " is of wrong type: " + fwk.getType());
+ }
+ if ( fwk.getArtifacts().size() != 1 ) {
+ throw new IOException("Extension " + EXT_NAME + " must have exactly one artifact: " + fwk.getArtifacts().size());
+ }
+ app.setFramework(fwk.getArtifacts().get(0).getId());
+ app.getExtensions().remove(fwk);
+ } else {
+ // use hard coded Apache Felix
+ app.setFramework(getFelixFrameworkId(null));
+ }
+
+ return app;
+ }
+
+ /**
+ * Read the feature
+ *
+ * @param file The feature file
+ * @param artifactManager The artifact manager to read the feature
+ * @return The read feature
+ * @throws IOException If reading fails
+ */
+ private static Feature getFeature(final String file,
+ final ArtifactManager artifactManager)
+ throws IOException {
+ final ArtifactHandler featureArtifact = artifactManager.getArtifactHandler(file);
+
+ try (final FileReader r = new FileReader(featureArtifact.getFile())) {
+ final Feature f = FeatureJSONReader.read(r, featureArtifact.getUrl());
+ return f;
+ }
+ }
+}
Propchange: sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/FeatureUtil.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/FeatureUtil.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/package-info.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/package-info.java?rev=1797391&view=auto
==============================================================================
--- sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/package-info.java (added)
+++ sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/package-info.java Fri Jun 2 14:02:13 2017
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+@org.osgi.annotation.versioning.Version("1.0.0")
+package org.apache.sling.feature.support;
+
+
Propchange: sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/package-info.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/package-info.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/spi/package-info.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/spi/package-info.java?rev=1797391&view=auto
==============================================================================
--- sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/spi/package-info.java (added)
+++ sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/spi/package-info.java Fri Jun 2 14:02:13 2017
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+@org.osgi.annotation.versioning.Version("1.0.0")
+package org.apache.sling.feature.support.spi;
+
+
Propchange: sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/spi/package-info.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/whiteboard/cziegeler/feature-support/src/main/java/org/apache/sling/feature/support/spi/package-info.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url