aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From csie...@apache.org
Subject svn commit: r1771182 - in /aries/trunk/component-dsl: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/aries/ src/main/java/org/apache/aries/osgi/ src/main/java/org/apache/aries/osgi/functional/ src...
Date Thu, 24 Nov 2016 16:35:49 GMT
Author: csierra
Date: Thu Nov 24 16:35:48 2016
New Revision: 1771182

URL: http://svn.apache.org/viewvc?rev=1771182&view=rev
Log:
Initial component-dsl commit

Added:
    aries/trunk/component-dsl/
    aries/trunk/component-dsl/LICENSE
    aries/trunk/component-dsl/README.md
    aries/trunk/component-dsl/bnd.bnd
    aries/trunk/component-dsl/pom.xml
    aries/trunk/component-dsl/src/
    aries/trunk/component-dsl/src/main/
    aries/trunk/component-dsl/src/main/java/
    aries/trunk/component-dsl/src/main/java/org/
    aries/trunk/component-dsl/src/main/java/org/apache/
    aries/trunk/component-dsl/src/main/java/org/apache/aries/
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/MOSGi.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGi.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGiOperation.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGiResult.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGiRunnable.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/BundleContextOSGiImpl.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/BundleMOSGi.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ChangeContextOSGiImpl.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ConfigurationOSGiImpl.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ConfigurationsOSGiImpl.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/JustOSGiImpl.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/MOSGiImpl.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/NothingOSGiImpl.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiImpl.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiOperationImpl.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiResultImpl.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OnCloseOSGiImpl.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Pipe.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/PrototypesMOSGi.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ServiceReferenceOSGi.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ServiceRegistrationOSGiImpl.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ServicesMOSGi.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Tracked.java
    aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Tuple.java

Added: aries/trunk/component-dsl/LICENSE
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/LICENSE?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/LICENSE (added)
+++ aries/trunk/component-dsl/LICENSE Thu Nov 24 16:35:48 2016
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   Licensed 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.

Added: aries/trunk/component-dsl/README.md
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/README.md?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/README.md (added)
+++ aries/trunk/component-dsl/README.md Thu Nov 24 16:35:48 2016
@@ -0,0 +1,2 @@
+# osgi-component-dsl
+A lightweight functional DSL to declare components in OSGi 

Added: aries/trunk/component-dsl/bnd.bnd
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/bnd.bnd?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/bnd.bnd (added)
+++ aries/trunk/component-dsl/bnd.bnd Thu Nov 24 16:35:48 2016
@@ -0,0 +1 @@
+Export-Package: org.apache.aries.osgi.functional
\ No newline at end of file

Added: aries/trunk/component-dsl/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/pom.xml?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/pom.xml (added)
+++ aries/trunk/component-dsl/pom.xml Thu Nov 24 16:35:48 2016
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+		 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+	<modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache</groupId>
+        <artifactId>apache</artifactId>
+        <version>17</version>
+        <relativePath />
+    </parent>
+	
+	<groupId>org.apache.aries.component-dsl</groupId>
+	<artifactId>component-dsl</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.1</version>
+				<configuration>
+					<source>1.8</source>
+					<target>1.8</target>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-jar-plugin</artifactId>
+				<version>3.0.1</version>
+				<configuration>
+					<archive>
+						<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+					</archive>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>biz.aQute.bnd</groupId>
+				<artifactId>bnd-maven-plugin</artifactId>
+				<version>3.4.0-SNAPSHOT</version>
+				<executions>
+					<execution>
+						<goals>
+							<goal>bnd-process</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+	<dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>6.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.cm</artifactId>
+            <version>1.5.0</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/MOSGi.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/MOSGi.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/MOSGi.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/MOSGi.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,29 @@
+/*
+ * 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.aries.osgi.functional;
+
+import java.util.function.Predicate;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public interface MOSGi<T> extends OSGi<T> {
+
+	OSGi<T> filter(Predicate<T> predicate);
+
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGi.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGi.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGi.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGi.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,123 @@
+/*
+ * 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.aries.osgi.functional;
+
+import org.apache.aries.osgi.functional.internal.BundleContextOSGiImpl;
+import org.apache.aries.osgi.functional.internal.BundleMOSGi;
+import org.apache.aries.osgi.functional.internal.ChangeContextOSGiImpl;
+import org.apache.aries.osgi.functional.internal.ConfigurationOSGiImpl;
+import org.apache.aries.osgi.functional.internal.ConfigurationsOSGiImpl;
+import org.apache.aries.osgi.functional.internal.JustOSGiImpl;
+import org.apache.aries.osgi.functional.internal.NothingOSGiImpl;
+import org.apache.aries.osgi.functional.internal.OnCloseOSGiImpl;
+import org.apache.aries.osgi.functional.internal.PrototypesMOSGi;
+import org.apache.aries.osgi.functional.internal.ServiceReferenceOSGi;
+import org.apache.aries.osgi.functional.internal.ServiceRegistrationOSGiImpl;
+import org.apache.aries.osgi.functional.internal.ServicesMOSGi;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceObjects;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+import java.util.Dictionary;
+import java.util.Map;
+import java.util.function.Function;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public interface OSGi<T> extends OSGiRunnable<T> {
+	Runnable NOOP = () -> {};
+
+	<S> OSGi<S> map(Function<T, S> function);
+
+	<S> OSGi<S> flatMap(Function<T, OSGi<S>> fun);
+
+	<S> OSGi<S> then(OSGi<S> next);
+
+	<S> OSGi<Void> foreach(Function<T, OSGi<S>> fun);
+
+	static OSGi<BundleContext> bundleContext() {
+
+		return new BundleContextOSGiImpl();
+	}
+
+	static MOSGi<Bundle> bundles(int stateMask) {
+		return new BundleMOSGi(stateMask);
+	}
+
+	static <T> OSGi<T> changeContext(
+		BundleContext bundleContext, OSGi<T> program) {
+
+		return new ChangeContextOSGiImpl<>(program, bundleContext);
+	}
+
+	static OSGi<Dictionary<String, ?>> configuration(String pid) {
+		return new ConfigurationOSGiImpl(pid);
+	}
+
+	static OSGi<Dictionary<String, ?>> configurations(String factoryPid) {
+		return new ConfigurationsOSGiImpl(factoryPid);
+	}
+
+	static <S> OSGi<S> nothing() {
+		return new NothingOSGiImpl<>();
+	}
+
+	static OSGi<Void> onClose(Runnable action) {
+		return new OnCloseOSGiImpl(action);
+	}
+
+	static <S> OSGi<S> just(S s) {
+		return new JustOSGiImpl<>(s);
+	}
+
+	static <T> MOSGi<ServiceObjects<T>> prototypes(Class<T> clazz) {
+		return prototypes(clazz, null);
+	}
+
+	static <T> MOSGi<ServiceObjects<T>> prototypes(
+		Class<T> clazz, String filterString) {
+
+		return new PrototypesMOSGi<>(clazz, filterString);
+	}
+
+	static <T, S extends T> OSGi<ServiceRegistration<T>> register(
+		Class<T> clazz, S service, Map<String, Object> properties) {
+
+		return new ServiceRegistrationOSGiImpl<>(
+			clazz, service, properties);
+	}
+
+	static <T> MOSGi<T> services(Class<T> clazz) {
+		return services(clazz, null);
+	}
+
+	static <T> MOSGi<T> services(Class<T> clazz, String filterString) {
+		return new ServicesMOSGi<>(clazz, filterString);
+	}
+
+	static <T> OSGi<ServiceReference<T>> serviceReferences(
+		Class<T> clazz, String filterString) {
+
+		return new ServiceReferenceOSGi<>(filterString, clazz);
+	}
+
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGiOperation.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGiOperation.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGiOperation.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGiOperation.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,29 @@
+/*
+ * 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.aries.osgi.functional;
+
+import org.osgi.framework.BundleContext;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public interface OSGiOperation<T> {
+
+	OSGiResult<T> run(BundleContext bundleContext);
+
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGiResult.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGiResult.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGiResult.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGiResult.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,25 @@
+/*
+ * 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.aries.osgi.functional;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public interface OSGiResult<T> {
+	public void close();
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGiRunnable.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGiRunnable.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGiRunnable.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/OSGiRunnable.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,31 @@
+/*
+ * 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.aries.osgi.functional;
+
+import org.osgi.framework.BundleContext;
+
+import java.util.function.Consumer;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public interface OSGiRunnable<T> {
+	OSGiResult<T> run(BundleContext bundleContext);
+
+	OSGiResult<T> run(BundleContext bundleContext, Consumer<T> andThen);
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/BundleContextOSGiImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/BundleContextOSGiImpl.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/BundleContextOSGiImpl.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/BundleContextOSGiImpl.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,42 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.osgi.framework.BundleContext;
+
+import java.util.function.Consumer;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public class BundleContextOSGiImpl extends OSGiImpl<BundleContext> {
+
+	public BundleContextOSGiImpl() {
+		super(bundleContext -> {
+			Pipe<Tuple<BundleContext>, Tuple<BundleContext>> added =
+				Pipe.create();
+
+			Consumer<Tuple<BundleContext>> addedSource = added.getSource();
+
+			return new OSGiResultImpl<>(
+				added, Pipe.create(),
+				() -> addedSource.accept(Tuple.create(bundleContext)),
+				NOOP);
+		});
+	}
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/BundleMOSGi.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/BundleMOSGi.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/BundleMOSGi.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/BundleMOSGi.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,160 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.apache.aries.osgi.functional.OSGi;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.util.tracker.BundleTracker;
+import org.osgi.util.tracker.BundleTrackerCustomizer;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public class BundleMOSGi extends MOSGiImpl<Bundle> {
+
+	private final int _stateMask;
+
+	public BundleMOSGi(int stateMask) {
+		super(bundleContext -> {
+			Pipe<Tuple<Bundle>, Tuple<Bundle>> added = Pipe.create();
+
+			Consumer<Tuple<Bundle>> addedSource = added.getSource();
+
+			Pipe<Tuple<Bundle>, Tuple<Bundle>> removed = Pipe.create();
+
+			Consumer<Tuple<Bundle>> removedSource = removed.getSource();
+
+			BundleTracker<Tuple<Bundle>> bundleTracker =
+				new BundleTracker<>(
+					bundleContext, stateMask,
+					new BundleTrackerCustomizer<Tuple<Bundle>>() {
+
+						@Override
+						public Tuple<Bundle> addingBundle(
+							Bundle bundle, BundleEvent bundleEvent) {
+
+							Tuple<Bundle> tuple = Tuple.create(bundle);
+
+							addedSource.accept(tuple);
+
+							return tuple;
+						}
+
+						@Override
+						public void modifiedBundle(
+							Bundle bundle, BundleEvent bundleEvent,
+							Tuple<Bundle> tuple) {
+
+							removedBundle(bundle, bundleEvent, tuple);
+
+							addingBundle(bundle, bundleEvent);
+						}
+
+						@Override
+						public void removedBundle(
+							Bundle bundle, BundleEvent bundleEvent,
+							Tuple<Bundle> tuple) {
+
+							removedSource.accept(tuple);
+						}
+					});
+
+			return new OSGiResultImpl<>(
+				added, removed, bundleTracker::open, bundleTracker::close);
+		});
+		_stateMask = stateMask;
+	}
+
+	@Override
+	public <S> OSGiImpl<S> flatMap(Function<Bundle, OSGi<S>> fun) {
+		return new OSGiImpl<>(bundleContext -> {
+			Pipe<Tuple<S>, Tuple<S>> added = Pipe.create();
+
+			Consumer<Tuple<S>> addedSource = added.getSource();
+
+			Pipe<Tuple<S>, Tuple<S>> removed = Pipe.create();
+
+			Consumer<Tuple<S>> removedSource = removed.getSource();
+
+			BundleTracker<Tracked<Bundle, S>> bundleTracker =
+				new BundleTracker<>(
+					bundleContext, _stateMask,
+					new BundleTrackerCustomizer<Tracked<Bundle, S>>() {
+
+						@Override
+						public Tracked<Bundle, S> addingBundle(
+							Bundle bundle, BundleEvent bundleEvent) {
+
+							OSGiImpl<S> program = (OSGiImpl<S>) fun.apply(
+								bundle);
+
+							OSGiResultImpl<S> result =
+								program._operation.run(bundleContext);
+
+							Tracked<Bundle, S> tracked = new Tracked<>();
+
+							tracked.service = bundle;
+							tracked.program = result;
+
+							result.added.map(s -> {
+								tracked.result = s;
+
+								addedSource.accept(s);
+
+								return s;
+							});
+
+							result.start.run();
+
+							return tracked;
+						}
+
+						@Override
+						public void modifiedBundle(
+							Bundle bundle, BundleEvent bundleEvent,
+							Tracked<Bundle, S> tracked) {
+
+							removedBundle(bundle, bundleEvent, tracked);
+
+							addingBundle(bundle, bundleEvent);
+						}
+
+						@Override
+						public void removedBundle(
+							Bundle bundle, BundleEvent bundleEvent,
+							Tracked<Bundle, S> tracked) {
+
+							tracked.program.close();
+
+							if (tracked.result != null) {
+								removedSource.accept(tracked.result);
+							}
+						}
+					});
+
+			return new OSGiResultImpl<>(
+				added, removed, bundleTracker::open, bundleTracker::close);
+
+		});
+	}
+
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ChangeContextOSGiImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ChangeContextOSGiImpl.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ChangeContextOSGiImpl.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ChangeContextOSGiImpl.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,33 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.apache.aries.osgi.functional.OSGi;
+import org.osgi.framework.BundleContext;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public class ChangeContextOSGiImpl<T> extends OSGiImpl<T> {
+
+	public ChangeContextOSGiImpl(
+		OSGi<T> program, BundleContext bundleContext) {
+
+		super(b -> ((OSGiImpl<T>) program)._operation.run(bundleContext));
+	}
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ConfigurationOSGiImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ConfigurationOSGiImpl.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ConfigurationOSGiImpl.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ConfigurationOSGiImpl.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,94 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ManagedService;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public class ConfigurationOSGiImpl
+	extends OSGiImpl<Dictionary<String, ?>> {
+
+	public ConfigurationOSGiImpl(String pid) {
+		super(bundleContext -> {
+			AtomicReference<Dictionary<String, ?>> atomicReference =
+				new AtomicReference<>(null);
+
+			AtomicReference<Tuple<Dictionary<String, ?>>>
+				tupleAtomicReference = new AtomicReference<>(
+				Tuple.create(null));
+
+			AtomicReference<ServiceRegistration<ManagedService>>
+				serviceRegistrationReferece = new AtomicReference<>(null);
+
+			Pipe<Tuple<Dictionary<String, ?>>, Tuple<Dictionary<String, ?>>>
+				added = Pipe.create();
+
+			Consumer<Tuple<Dictionary<String, ?>>> addedSource =
+				added.getSource();
+
+			Pipe<Tuple<Dictionary<String, ?>>, Tuple<Dictionary<String, ?>>>
+				removed = Pipe.create();
+
+			Consumer<Tuple<Dictionary<String, ?>>> removedSource =
+				removed.getSource();
+
+			Runnable start = () ->
+				serviceRegistrationReferece.set(
+					bundleContext.registerService(
+						ManagedService.class,
+						properties -> {
+							while (!atomicReference.compareAndSet(
+								tupleAtomicReference.get().t,
+								properties)) {
+							}
+
+							Tuple<Dictionary<String, ?>> old =
+								tupleAtomicReference.get();
+
+							if (old != null) {
+								removedSource.accept(old);
+							}
+
+							Tuple<Dictionary<String, ?>> tuple =
+								Tuple.create(properties);
+
+							if (old != null) {
+								addedSource.accept(tuple);
+							}
+
+							tupleAtomicReference.set(tuple);
+						},
+						new Hashtable<String, Object>() {{
+							put("service.pid", pid);
+						}}));
+
+			return new OSGiResultImpl<>(
+				added, removed, start,
+				() -> serviceRegistrationReferece.get().unregister());
+		});
+	}
+
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ConfigurationsOSGiImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ConfigurationsOSGiImpl.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ConfigurationsOSGiImpl.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ConfigurationsOSGiImpl.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,130 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedServiceFactory;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public class ConfigurationsOSGiImpl
+	extends OSGiImpl<Dictionary<String, ?>> {
+
+	public ConfigurationsOSGiImpl(String factoryPid) {
+		super(bundleContext -> {
+			Map<String, Tuple<Dictionary<String, ?>>> results =
+				new ConcurrentHashMap<>();
+
+			AtomicReference<ServiceRegistration<ManagedServiceFactory>>
+				serviceRegistrationReference = new AtomicReference<>(null);
+
+			Pipe<Tuple<Dictionary<String, ?>>, Tuple<Dictionary<String, ?>>>
+				added = Pipe.create();
+
+			Consumer<Tuple<Dictionary<String, ?>>> addedSource =
+				added.getSource();
+
+			Pipe<Tuple<Dictionary<String, ?>>, Tuple<Dictionary<String, ?>>>
+				removed = Pipe.create();
+
+			Consumer<Tuple<Dictionary<String, ?>>> removedSource =
+				removed.getSource();
+
+			Runnable start = () ->
+				serviceRegistrationReference.set(
+					bundleContext.registerService(
+						ManagedServiceFactory.class,
+						new ConfigurationsManagedServiceFactory(
+							results, removedSource, addedSource),
+						new Hashtable<String, Object>() {{
+							put("service.pid", factoryPid);
+						}}));
+
+
+			return new OSGiResultImpl<>(added, removed, start,
+				() -> {
+					serviceRegistrationReference.get().unregister();
+
+					for (Tuple<Dictionary<String, ?>> tuple :
+						results.values()) {
+
+						removedSource.accept(tuple);
+					}
+				});
+		});
+	}
+
+	private static class ConfigurationsManagedServiceFactory
+		implements ManagedServiceFactory {
+
+		private final Map<String, Tuple<Dictionary<String, ?>>> _results;
+
+		private final Consumer<Tuple<Dictionary<String, ?>>> _removedSource;
+		private final Consumer<Tuple<Dictionary<String, ?>>> _addedSource;
+
+		public ConfigurationsManagedServiceFactory(
+			Map<String, Tuple<Dictionary<String, ?>>> results,
+			Consumer<Tuple<Dictionary<String, ?>>> removedSource,
+			Consumer<Tuple<Dictionary<String, ?>>> addedSource) {
+
+			_results = results;
+			_removedSource = removedSource;
+			_addedSource = addedSource;
+		}
+
+		@Override
+		public void deleted(String s) {
+			Tuple<Dictionary<String, ?>> tuple =
+				_results.remove(s);
+
+			_removedSource.accept(tuple);
+		}
+
+		@Override
+		public String getName() {
+			return "Functional OSGi Managed Service Factory";
+		}
+
+		@Override
+		public void updated(
+			String s, Dictionary<String, ?> dictionary)
+			throws ConfigurationException {
+
+			Tuple<Dictionary<String, ?>> tuple = Tuple.create(
+				dictionary);
+
+			Tuple<Dictionary<String, ?>> old = _results.put(s, tuple);
+
+			if (old != null) {
+				_removedSource.accept(old);
+			}
+
+			_addedSource.accept(tuple);
+		}
+
+	}
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/JustOSGiImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/JustOSGiImpl.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/JustOSGiImpl.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/JustOSGiImpl.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,42 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.apache.aries.osgi.functional.OSGi;
+
+import java.util.function.Consumer;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public class JustOSGiImpl<S> extends OSGiImpl<S> {
+
+	public JustOSGiImpl(S s) {
+		super(((bundleContext) -> {
+
+			Pipe<Tuple<S>, Tuple<S>> added = Pipe.create();
+
+			Consumer<Tuple<S>> source = added.getSource();
+
+			return new OSGiResultImpl<>(
+				added, Pipe.create(),
+				() -> source.accept(Tuple.create(s)), OSGi.NOOP);
+		}));
+	}
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/MOSGiImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/MOSGiImpl.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/MOSGiImpl.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/MOSGiImpl.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,47 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.apache.aries.osgi.functional.MOSGi;
+import org.apache.aries.osgi.functional.OSGi;
+
+import java.util.function.Predicate;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public class MOSGiImpl<T> extends OSGiImpl<T>
+	implements MOSGi<T> {
+
+	MOSGiImpl(OSGiOperationImpl<T> operation) {
+		super(operation);
+	}
+
+	@Override
+	public OSGi<T> filter(Predicate<T> predicate) {
+		return flatMap(t -> {
+			if (predicate.test(t)) {
+				return OSGi.just(t);
+			}
+			else {
+				return OSGi.nothing();
+			}
+		});
+	}
+
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/NothingOSGiImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/NothingOSGiImpl.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/NothingOSGiImpl.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/NothingOSGiImpl.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,31 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.apache.aries.osgi.functional.OSGi;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public class NothingOSGiImpl<S> extends OSGiImpl<S> {
+
+	public NothingOSGiImpl() {
+		super(((bundleContext) -> new OSGiResultImpl<>(
+			Pipe.create(), Pipe.create(), OSGi.NOOP, OSGi.NOOP)));
+	}
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiImpl.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiImpl.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiImpl.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,169 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.apache.aries.osgi.functional.OSGi;
+import org.apache.aries.osgi.functional.OSGiResult;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public class OSGiImpl<T> implements OSGi<T> {
+
+	public OSGiOperationImpl<T> _operation;
+
+	public OSGiImpl(OSGiOperationImpl<T> operation) {
+		_operation = operation;
+	}
+
+	@Override
+	public <S> OSGiImpl<S> flatMap(Function<T, OSGi<S>> fun) {
+		return new OSGiImpl<>(
+			((bundleContext) -> {
+				Map<Object, OSGiResult<S>> identities = new IdentityHashMap<>();
+
+				AtomicReference<Runnable> closeReference =
+					new AtomicReference<>(NOOP);
+
+				Pipe<Tuple<S>, Tuple<S>> added = Pipe.create();
+
+				Consumer<Tuple<S>> addedSource = added.getSource();
+
+				OSGiResultImpl<S> osgiResult = new OSGiResultImpl<>(
+					added, Pipe.create(), null,
+					() -> {
+						synchronized (identities) {
+							identities.values().forEach(OSGiResult::close);
+						}
+
+						closeReference.get().run();
+					});
+
+				osgiResult.start = () -> {
+					OSGiResultImpl<T> or1 = _operation.run(bundleContext);
+
+					closeReference.set(or1.close);
+
+					or1.added.map(t -> {
+						OSGi<S> program = fun.apply(t.t);
+
+						OSGiResult<S> or2 = program.run(
+							bundleContext,
+							s -> addedSource.accept(Tuple.create(s)));
+
+						identities.put(t.original, or2);
+
+						return null;
+					});
+
+					or1.removed.map(t -> {
+						synchronized (identities) {
+							OSGiResult<S> osgiResult1 = identities.remove(
+								t.original);
+
+							if (osgiResult1 != null) {
+								osgiResult1.close();
+							}
+						}
+
+						return null;
+					});
+
+					or1.start.run();
+				};
+
+				return osgiResult;
+			}
+			));
+	}
+
+	@Override
+	public <S> OSGi<Void> foreach(Function<T, OSGi<S>> fun) {
+		return this.flatMap(fun).map(x -> null);
+	}
+
+	@Override
+	public <S> OSGi<S> map(Function<T, S> function) {
+		return new OSGiImpl<>(((bundleContext) -> {
+			OSGiResultImpl<T> osgiResult = _operation.run(bundleContext);
+
+			return new OSGiResultImpl<>(
+				osgiResult.added.map(t -> t.map(function)),
+				osgiResult.removed.map(t -> t.map(function)),
+				osgiResult.start, osgiResult.close);
+		}));
+	}
+
+	@Override
+	public OSGiResult<T> run(BundleContext bundleContext) {
+		return run(bundleContext, x -> {});
+	}
+
+	@Override
+	public OSGiResult<T> run(BundleContext bundleContext, Consumer<T> andThen) {
+		OSGiResultImpl<T> osgiResult = _operation.run(bundleContext);
+
+		osgiResult.added.map(x -> {andThen.accept(x.t); return null;});
+
+		osgiResult.start.run();
+
+		return new OSGiResultImpl<>(
+			osgiResult.added, osgiResult.removed,
+			osgiResult.start, osgiResult.close);
+	}
+
+	@Override
+	public <S> OSGi<S> then(OSGi<S> next) {
+		return flatMap(ignored -> next);
+	}
+
+	static Filter buildFilter(
+		BundleContext bundleContext, String filterString, Class<?> clazz) {
+
+		Filter filter;
+
+		try {
+			if (filterString == null) {
+				filter = bundleContext.createFilter(
+					"(objectClass=" + clazz.getName() + ")");
+			}
+			else {
+				filter = bundleContext.createFilter(
+					"(&(objectClass=" + clazz.getName() + ")" +
+						filterString + ")");
+			}
+		}
+		catch (InvalidSyntaxException e) {
+			throw new RuntimeException(e);
+		}
+
+		return filter;
+	}
+
+}
+
+

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiOperationImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiOperationImpl.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiOperationImpl.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiOperationImpl.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,31 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.apache.aries.osgi.functional.OSGiOperation;
+import org.osgi.framework.BundleContext;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+interface OSGiOperationImpl<T> extends OSGiOperation<T> {
+
+	@Override
+	OSGiResultImpl<T> run(BundleContext bundleContext);
+
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiResultImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiResultImpl.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiResultImpl.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OSGiResultImpl.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,47 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.apache.aries.osgi.functional.OSGiResult;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public class OSGiResultImpl<T> implements OSGiResult<T> {
+
+	public Pipe<?, Tuple<T>> added;
+	public Pipe<?, Tuple<T>> removed;
+	public Runnable start;
+	public Runnable close;
+
+	public OSGiResultImpl(
+		Pipe<?, Tuple<T>> added, Pipe<?, Tuple<T>> removed,
+		Runnable start, Runnable close) {
+
+		this.added = added;
+		this.removed = removed;
+		this.start = start;
+		this.close = close;
+	}
+
+	@Override
+	public void close() {
+		close.run();
+	}
+
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OnCloseOSGiImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OnCloseOSGiImpl.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OnCloseOSGiImpl.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/OnCloseOSGiImpl.java Thu Nov 24 16:35:48 2016
@@ -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.
+ */
+
+package org.apache.aries.osgi.functional.internal;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public class OnCloseOSGiImpl extends OSGiImpl<Void> {
+
+	public OnCloseOSGiImpl(Runnable action) {
+		super(bundleContext -> {
+			Pipe<Tuple<Void>, Tuple<Void>> pipe = Pipe.create();
+
+			return new OSGiResultImpl<>(
+				pipe, Pipe.create(),
+				() -> pipe.getSource().accept(Tuple.create(null)),
+				action::run);
+		});
+	}
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Pipe.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Pipe.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Pipe.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Pipe.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,48 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+class Pipe<I, O> {
+
+	private Function<I, O> pipe;
+
+	private Pipe(Function<I, O> fun) {
+		this.pipe = fun;
+	}
+
+	public static <T> Pipe<T, T> create() {
+		return new Pipe<>(x -> x);
+	}
+
+	public Consumer<I> getSource() {
+		return i -> pipe.apply(i);
+	}
+
+	<U> Pipe<I, U> map(Function<O, U> fun) {
+		this.pipe = (Function)this.pipe.andThen(fun);
+
+		return (Pipe<I, U>)this;
+	}
+
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/PrototypesMOSGi.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/PrototypesMOSGi.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/PrototypesMOSGi.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/PrototypesMOSGi.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,182 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.apache.aries.osgi.functional.OSGi;
+import org.apache.aries.osgi.functional.OSGiResult;
+import org.osgi.framework.ServiceObjects;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public class PrototypesMOSGi<T>
+	extends MOSGiImpl<ServiceObjects<T>> {
+
+	private final String _filterString;
+
+	private final Class<T> _clazz;
+
+	public PrototypesMOSGi(Class<T> clazz, String filterString) {
+		super(bundleContext -> {
+			Pipe<Tuple<ServiceObjects<T>>, Tuple<ServiceObjects<T>>> added =
+				Pipe.create();
+
+			Pipe<Tuple<ServiceObjects<T>>, Tuple<ServiceObjects<T>>>
+				removed = Pipe.create();
+
+			Consumer<Tuple<ServiceObjects<T>>> addedSource =
+				added.getSource();
+
+			Consumer<Tuple<ServiceObjects<T>>> removedSource =
+				removed.getSource();
+
+			ServiceTracker<T, Tuple<ServiceObjects<T>>> serviceTracker =
+				new ServiceTracker<>(
+					bundleContext,
+					OSGiImpl.buildFilter(
+						bundleContext, filterString, clazz),
+					new ServiceTrackerCustomizer
+						<T, Tuple<ServiceObjects<T>>>() {
+
+						@Override
+						public Tuple<ServiceObjects<T>> addingService(
+							ServiceReference<T> reference) {
+
+							ServiceObjects<T> serviceObjects =
+								bundleContext.getServiceObjects(reference);
+
+							Tuple<ServiceObjects<T>> tuple =
+								Tuple.create(serviceObjects);
+
+							addedSource.accept(tuple);
+
+							return tuple;
+						}
+
+						@Override
+						public void modifiedService(
+							ServiceReference<T> reference,
+							Tuple<ServiceObjects<T>> service) {
+
+							removedService(reference, service);
+
+							addingService(reference);
+						}
+
+						@Override
+						public void removedService(
+							ServiceReference<T> reference,
+							Tuple<ServiceObjects<T>> tuple) {
+
+							removedSource.accept(tuple);
+						}
+					});
+
+			return new OSGiResultImpl<>(
+				added, removed, serviceTracker::open,
+				serviceTracker::close);
+		});
+
+		_filterString = filterString;
+		_clazz = clazz;
+	}
+
+	@Override
+	public <S> OSGiImpl<S> flatMap(
+		Function<ServiceObjects<T>, OSGi<S>> fun) {
+		return new OSGiImpl<>(bundleContext -> {
+			Pipe<Tuple<S>, Tuple<S>> added = Pipe.create();
+
+			Pipe<Tuple<S>, Tuple<S>> removed = Pipe.create();
+
+			Consumer<Tuple<S>> addedSource = added.getSource();
+
+			Consumer<Tuple<S>> removedSource = removed.getSource();
+
+			ServiceTracker<T, Tracked<ServiceObjects<T>, S>>
+				serviceTracker = new ServiceTracker<>(
+				bundleContext,
+				buildFilter(bundleContext, _filterString, _clazz),
+				new ServiceTrackerCustomizer
+					<T, Tracked<ServiceObjects<T>, S>>() {
+
+					@Override
+					public Tracked<ServiceObjects<T>, S> addingService(
+						ServiceReference<T> reference) {
+
+						ServiceObjects<T> serviceObjects =
+							bundleContext.getServiceObjects(
+								reference);
+
+						OSGi<S> program = fun.apply(serviceObjects);
+
+						Tracked<ServiceObjects<T>, S> tracked =
+							new Tracked<>();
+
+						OSGiResult<S> result = program.run(
+							bundleContext, s -> {
+								Tuple<S> tuple = Tuple.create(s);
+
+								tracked.result = tuple;
+
+								addedSource.accept(tuple);
+							}
+						);
+
+						tracked.program = result;
+						tracked.service = serviceObjects;
+
+						return tracked;
+					}
+
+					@Override
+					public void modifiedService(
+						ServiceReference<T> reference,
+						Tracked<ServiceObjects<T>, S> tracked) {
+
+						removedService(reference, tracked);
+
+						addingService(reference);
+					}
+
+					@Override
+					public void removedService(
+						ServiceReference<T> reference,
+						Tracked<ServiceObjects<T>, S> tracked) {
+
+						tracked.program.close();
+
+						if (tracked.result != null) {
+							removedSource.accept(tracked.result);
+						}
+					}
+				});
+
+			return new OSGiResultImpl<>(
+				added, removed, serviceTracker::open,
+				serviceTracker::close);
+		});
+	}
+
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ServiceReferenceOSGi.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ServiceReferenceOSGi.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ServiceReferenceOSGi.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ServiceReferenceOSGi.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,81 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+import java.util.function.Consumer;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public class ServiceReferenceOSGi<T>
+	extends OSGiImpl<ServiceReference<T>> {
+
+	public ServiceReferenceOSGi(String filterString, Class<T> clazz) {
+		super(bundleContext -> {
+			Pipe<Tuple<ServiceReference<T>>, Tuple<ServiceReference<T>>>
+				added = Pipe.create();
+
+			Consumer<Tuple<ServiceReference<T>>> addedSource =
+				added.getSource();
+
+			Pipe<Tuple<ServiceReference<T>>, Tuple<ServiceReference<T>>>
+				removed = Pipe.create();
+
+			Consumer<Tuple<ServiceReference<T>>> removedSource =
+				removed.getSource();
+
+			ServiceTracker<T, Tuple<ServiceReference<T>>> serviceTracker =
+				new ServiceTracker<T, Tuple<ServiceReference<T>>>(
+					bundleContext,
+					OSGiImpl.buildFilter(
+						bundleContext, filterString, clazz), null) {
+
+					@Override
+					public Tuple<ServiceReference<T>> addingService(
+						ServiceReference<T> reference) {
+
+						Tuple<ServiceReference<T>> tuple = Tuple.create(
+							reference);
+
+						addedSource.accept(tuple);
+
+						return tuple;
+					}
+
+					@Override
+					public void removedService(
+						ServiceReference<T> reference,
+						Tuple<ServiceReference<T>> t) {
+
+						super.removedService(reference, t);
+
+						removedSource.accept(t);
+					}
+				};
+
+			return new OSGiResultImpl<>(
+				added, removed, serviceTracker::open,
+				serviceTracker::close);
+
+		});
+	}
+
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ServiceRegistrationOSGiImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ServiceRegistrationOSGiImpl.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ServiceRegistrationOSGiImpl.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ServiceRegistrationOSGiImpl.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,63 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.osgi.framework.ServiceRegistration;
+
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.function.Consumer;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public class ServiceRegistrationOSGiImpl<T, S extends T>
+	extends OSGiImpl<ServiceRegistration<T>> {
+
+	public ServiceRegistrationOSGiImpl(
+		Class<T> clazz, S service, Map<String, Object> properties) {
+
+		super(bundleContext -> {
+			ServiceRegistration<T> serviceRegistration =
+				bundleContext.registerService(
+					clazz, service, new Hashtable<>(properties));
+
+			Pipe<Tuple
+				<ServiceRegistration<T>>, Tuple<ServiceRegistration<T>>>
+				added = Pipe.create();
+
+			Consumer<Tuple<ServiceRegistration<T>>> addedSource =
+				added.getSource();
+
+			Tuple<ServiceRegistration<T>> tuple = Tuple.create(
+				serviceRegistration);
+
+			return new OSGiResultImpl<>(
+				added, Pipe.create(),
+				() -> addedSource.accept(tuple),
+				() -> {
+					try {
+						serviceRegistration.unregister();
+					}
+					catch (Exception e) {
+					}
+				});
+		});
+	}
+
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ServicesMOSGi.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ServicesMOSGi.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ServicesMOSGi.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/ServicesMOSGi.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,188 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.apache.aries.osgi.functional.OSGi;
+import org.apache.aries.osgi.functional.OSGiResult;
+import org.osgi.framework.ServiceObjects;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+public class ServicesMOSGi<T> extends MOSGiImpl<T> {
+
+	private final String _filterString;
+
+	private final Class<T> _clazz;
+
+	public ServicesMOSGi(Class<T> clazz, String filterString) {
+		super(bundleContext -> {
+			Pipe<Tuple<T>, Tuple<T>> added = Pipe.create();
+
+			Pipe<Tuple<T>, Tuple<T>> removed = Pipe.create();
+
+			Consumer<Tuple<T>> addedSource = added.getSource();
+
+			Consumer<Tuple<T>> removedSource = removed.getSource();
+
+			ServiceTracker<T, Tuple<T>> serviceTracker =
+				new ServiceTracker<>(
+					bundleContext,
+					OSGiImpl.buildFilter(
+						bundleContext, filterString, clazz),
+					new ServiceTrackerCustomizer<T, Tuple<T>>() {
+						@Override
+						public Tuple<T> addingService(
+							ServiceReference<T> reference) {
+
+							ServiceObjects<T> serviceObjects =
+								bundleContext.getServiceObjects(reference);
+
+							T service = serviceObjects.getService();
+
+							Tuple<T> tuple = Tuple.create(service);
+
+							addedSource.accept(tuple);
+
+							return tuple;
+						}
+
+						@Override
+						public void modifiedService(
+							ServiceReference<T> reference,
+							Tuple<T> service) {
+
+							removedService(reference, service);
+
+							addingService(reference);
+						}
+
+						@Override
+						public void removedService(
+							ServiceReference<T> reference, Tuple<T> tuple) {
+
+							ServiceObjects<T> serviceObjects =
+								bundleContext.getServiceObjects(reference);
+
+							removedSource.accept(tuple);
+
+							serviceObjects.ungetService(tuple.t);
+						}
+					});
+
+			return new OSGiResultImpl<>(
+				added, removed, serviceTracker::open,
+				serviceTracker::close);
+		});
+
+		_filterString = filterString;
+
+		_clazz = clazz;
+	}
+
+	@Override
+	public <S> OSGiImpl<S> flatMap(Function<T, OSGi<S>> fun) {
+		return new OSGiImpl<>(bundleContext -> {
+			Pipe<Tuple<S>, Tuple<S>> added = Pipe.create();
+
+			Pipe<Tuple<S>, Tuple<S>> removed = Pipe.create();
+
+			Consumer<Tuple<S>> addedSource = added.getSource();
+
+			Consumer<Tuple<S>> removedSource = removed.getSource();
+
+			ServiceTracker<T, Tracked<T, S>> serviceTracker =
+				new ServiceTracker<>(
+					bundleContext,
+					buildFilter(
+						bundleContext, _filterString, _clazz),
+					new ServiceTrackerCustomizer<T, Tracked<T, S>>() {
+						@Override
+						public Tracked<T, S> addingService(
+							ServiceReference<T> reference) {
+
+							ServiceObjects<T> serviceObjects =
+								bundleContext.getServiceObjects(
+									reference);
+
+							T service = serviceObjects.getService();
+
+							OSGi<S> program = fun.apply(service);
+
+							Tracked<T, S> tracked = new Tracked<>();
+
+							OSGiResult<S> result = program.run(
+								bundleContext, s -> {
+									Tuple<S> tuple = Tuple.create(s);
+
+									tracked.result = tuple;
+
+									addedSource.accept(tuple);
+								}
+							);
+
+							tracked.service = service;
+							tracked.program = result;
+
+							return tracked;
+						}
+
+						@Override
+						public void modifiedService(
+							ServiceReference<T> reference,
+							Tracked<T, S> tracked) {
+
+							removedService(reference, tracked);
+
+							addingService(reference);
+						}
+
+						@Override
+						public void removedService(
+							ServiceReference<T> reference,
+							Tracked<T, S> tracked) {
+
+							tracked.program.close();
+
+							if (tracked.result != null) {
+								removedSource.accept(tracked.result);
+							}
+
+							ServiceObjects<T> serviceObjects =
+								bundleContext.getServiceObjects(
+									reference);
+
+							serviceObjects.ungetService(
+								tracked.service);
+						}
+					});
+
+			return new OSGiResultImpl<>(
+				added, removed, serviceTracker::open,
+				serviceTracker::close);
+
+		});
+	}
+
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Tracked.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Tracked.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Tracked.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Tracked.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,32 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import org.apache.aries.osgi.functional.OSGiResult;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+class Tracked<T, S> {
+
+	T service = null;
+	OSGiResult<S> program = null;
+
+	Tuple<S> result = null;
+
+}

Added: aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Tuple.java
URL: http://svn.apache.org/viewvc/aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Tuple.java?rev=1771182&view=auto
==============================================================================
--- aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Tuple.java (added)
+++ aries/trunk/component-dsl/src/main/java/org/apache/aries/osgi/functional/internal/Tuple.java Thu Nov 24 16:35:48 2016
@@ -0,0 +1,44 @@
+/*
+ * 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.aries.osgi.functional.internal;
+
+import java.util.function.Function;
+
+/**
+ * @author Carlos Sierra Andrés
+ */
+class Tuple<T> {
+
+	public Object original;
+	public T t;
+
+	private Tuple(Object original, T t) {
+		this.original = original;
+		this.t = t;
+	}
+
+	public <S> Tuple<S> map(Function<T, S> fun) {
+		return new Tuple<>(original, fun.apply(t));
+	}
+
+	public static <T> Tuple<T> create(T t) {
+		return new Tuple<>(t, t);
+	}
+
+}



Mime
View raw message