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);
+       }
+
+}


Reply via email to