├── project ├── build.properties ├── plugins.sbt └── CentralRequirementsPlugin.scala ├── .gitattributes ├── version.sbt ├── docs └── img │ └── logo.png ├── core ├── src │ ├── main │ │ ├── scala-scalaz-7.2.x │ │ │ └── delorean │ │ │ │ └── compatibility.scala │ │ ├── scala-scalaz-7.1.x │ │ │ └── delorean │ │ │ │ └── compatibility.scala │ │ └── scala │ │ │ └── delorean │ │ │ └── package.scala │ └── test │ │ └── scala │ │ └── delorean │ │ └── ConversionSpec.scala └── build.sbt ├── notes └── 1.0.markdown ├── project.sbt ├── .gitignore ├── .travis.yml ├── README.md └── LICENSE /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=0.13.12 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.graffle binary 2 | *.enc binary 3 | -------------------------------------------------------------------------------- /version.sbt: -------------------------------------------------------------------------------- 1 | version in ThisBuild := "1.2.0-SNAPSHOT" 2 | -------------------------------------------------------------------------------- /docs/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Verizon/delorean/HEAD/docs/img/logo.png -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | 2 | addSbtPlugin("io.verizon.build" % "sbt-rig" % "1.2.26") 3 | -------------------------------------------------------------------------------- /core/src/main/scala-scalaz-7.2.x/delorean/compatibility.scala: -------------------------------------------------------------------------------- 1 | package delorean 2 | 3 | object compatibility 4 | 5 | -------------------------------------------------------------------------------- /notes/1.0.markdown: -------------------------------------------------------------------------------- 1 | + Initial release 2 | + Supports both Scala 2.11 and Scala 2.10 3 | + Removed build customisations that are now in the main sbt-verizon plugin 4 | -------------------------------------------------------------------------------- /project.sbt: -------------------------------------------------------------------------------- 1 | 2 | organization in Global := "io.verizon.delorean" 3 | 4 | scalaVersion in Global := crossScalaVersions.value.head 5 | 6 | crossScalaVersions in Global := Seq("2.11.7", "2.10.4", "2.12.1") 7 | 8 | lazy val delorean = project.in(file(".")).aggregate(core) 9 | 10 | lazy val core = project 11 | 12 | enablePlugins(DisablePublishingPlugin) 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | release-notes 2 | logs 3 | *.db 4 | project/project 5 | project/target 6 | target 7 | lib_managed 8 | src_managed 9 | project/boot 10 | tmp 11 | .history 12 | dist 13 | .DS_Store 14 | .cache 15 | .settings 16 | .classpath 17 | bin 18 | .class 19 | .project 20 | .ivy2 21 | .lib 22 | .idea 23 | *.swp 24 | sbt 25 | *~ 26 | tags 27 | _site 28 | *.local.yml 29 | -------------------------------------------------------------------------------- /core/src/main/scala-scalaz-7.1.x/delorean/compatibility.scala: -------------------------------------------------------------------------------- 1 | package delorean 2 | 3 | import scalaz.\/ 4 | import scalaz.concurrent.Task 5 | 6 | object compatibility { 7 | implicit final class BedazledTask[A](val task: Task[A]) extends AnyVal { 8 | def unsafePerformAsync(g: (Throwable \/ A) => Unit): Unit = task.runAsync(g) 9 | def unsafePerformSync: A = task.run 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /core/build.sbt: -------------------------------------------------------------------------------- 1 | 2 | val scalazVersion = sys.env.getOrElse("SCALAZ_VERSION", "7.1.11") 3 | val scalazMajorVersion = scalazVersion.take(3) 4 | 5 | libraryDependencies ++= { 6 | 7 | Seq( 8 | "org.scalaz" %% "scalaz-core" % scalazVersion, 9 | "org.scalaz" %% "scalaz-concurrent" % scalazVersion 10 | ) 11 | } 12 | 13 | // Add scalaz version to project version 14 | version := { 15 | version.value match { 16 | case v if v.endsWith("-SNAPSHOT") => 17 | val replacement = s"-scalaz-$scalazMajorVersion-SNAPSHOT" 18 | v.replaceAll("-SNAPSHOT", replacement) 19 | case v => 20 | s"${v}-scalaz-$scalazMajorVersion" 21 | } 22 | } 23 | 24 | unmanagedSourceDirectories in Compile += 25 | (sourceDirectory in Compile).value / 26 | (s"scala-scalaz-$scalazMajorVersion.x") 27 | -------------------------------------------------------------------------------- /project/CentralRequirementsPlugin.scala: -------------------------------------------------------------------------------- 1 | package verizon.build 2 | 3 | import sbt._, Keys._ 4 | import xerial.sbt.Sonatype.autoImport.sonatypeProfileName 5 | 6 | object CentralRequirementsPlugin extends AutoPlugin { 7 | 8 | override def trigger = allRequirements 9 | 10 | override def requires = RigPlugin 11 | 12 | override lazy val projectSettings = Seq( 13 | sonatypeProfileName := "io.verizon", 14 | pomExtra in Global := { 15 | 16 | 17 | djspiewak 18 | Daniel Spiewak 19 | http://github.com/djspiewak 20 | 21 | 22 | timperrett 23 | Timothy Perrett 24 | http://github.com/timperrett 25 | 26 | 27 | ceedubs 28 | Cody Allen 29 | https://github.com/ceedubs 30 | 31 | 32 | }, 33 | licenses := Seq("Apache-2.0" -> url("https://www.apache.org/licenses/LICENSE-2.0.html")), 34 | homepage := Some(url("http://verizon.github.io/delorean/")), 35 | scmInfo := Some(ScmInfo(url("https://github.com/verizon/delorean"), 36 | "git@github.com:verizon/delorean.git")) 37 | ) 38 | } 39 | -------------------------------------------------------------------------------- /core/src/main/scala/delorean/package.scala: -------------------------------------------------------------------------------- 1 | //: ---------------------------------------------------------------------------- 2 | //: Copyright (C) 2016 Verizon. All Rights Reserved. 3 | //: 4 | //: Licensed under the Apache License, Version 2.0 (the "License"); 5 | //: you may not use this file except in compliance with the License. 6 | //: You may obtain a copy of the License at 7 | //: 8 | //: http://www.apache.org/licenses/LICENSE-2.0 9 | //: 10 | //: Unless required by applicable law or agreed to in writing, software 11 | //: distributed under the License is distributed on an "AS IS" BASIS, 12 | //: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | //: See the License for the specific language governing permissions and 14 | //: limitations under the License. 15 | //: 16 | //: ---------------------------------------------------------------------------- 17 | import scala.concurrent.{ExecutionContext, Future, Promise} 18 | import scala.util.{Failure, Success} 19 | 20 | import scalaz.{-\/, \/-} 21 | import scalaz.concurrent.{Strategy, Task} 22 | import delorean.compatibility._ 23 | 24 | package object delorean { 25 | 26 | implicit class FutureAPI[A](self: => Future[A]) { 27 | 28 | def toTask(implicit ec: ExecutionContext, S: Strategy): Task[A] = { 29 | Task async { cb => 30 | self onComplete { 31 | case Success(a) => S { cb(\/-(a)) } 32 | case Failure(t) => S { cb(-\/(t)) } 33 | } 34 | } 35 | } 36 | } 37 | 38 | implicit class TaskAPI[A](val self: Task[A]) extends AnyVal { 39 | 40 | def unsafeToFuture(): Future[A] = { 41 | val p = Promise[A]() 42 | 43 | self unsafePerformAsync { 44 | case \/-(a) => p.complete(Success(a)); () 45 | case -\/(t) => p.complete(Failure(t)); () 46 | } 47 | 48 | p.future 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: scala 2 | 3 | matrix: 4 | include: 5 | # scala 2.10 6 | - jdk: oraclejdk8 7 | scala: 2.10.6 8 | env: SCALAZ_VERSION=7.1.11 9 | - jdk: oraclejdk8 10 | scala: 2.10.6 11 | env: SCALAZ_VERSION=7.2.8 12 | # scala 2.11 13 | - jdk: oraclejdk8 14 | scala: 2.11.8 15 | env: SCALAZ_VERSION=7.1.11 16 | - jdk: oraclejdk8 17 | scala: 2.11.8 18 | env: SCALAZ_VERSION=7.2.8 19 | # scala 2.12 20 | - jdk: oraclejdk8 21 | scala: 2.12.1 22 | env: SCALAZ_VERSION=7.1.11 23 | - jdk: oraclejdk8 24 | scala: 2.12.1 25 | env: SCALAZ_VERSION=7.2.8 26 | 27 | branches: 28 | only: 29 | - master 30 | 31 | before_script: 32 | - "if [ $TRAVIS_PULL_REQUEST = 'false' ]; then git checkout -qf $TRAVIS_BRANCH; fi" 33 | 34 | script: 35 | - | 36 | if [ $TRAVIS_PULL_REQUEST = 'false' ]; then 37 | if [ $RELEASE_ON_PUSH = 'false' ]; then 38 | sbt test coverageReport 39 | else 40 | sbt ++$TRAVIS_SCALA_VERSION 'release with-defaults' 41 | fi 42 | else 43 | sbt test coverageReport 44 | fi 45 | - find $HOME/.sbt -name "*.lock" | xargs rm 46 | - find $HOME/.ivy2 -name "ivydata-*.properties" | xargs rm 47 | 48 | cache: 49 | directories: 50 | - $HOME/.ivy2/cache 51 | - $HOME/.sbt/boot/scala-$TRAVIS_SCALA_VERSION 52 | 53 | after_success: 54 | - find $HOME/.sbt -name "*.lock" | xargs rm 55 | - find $HOME/.ivy2 -name "ivydata-*.properties" | xargs rm 56 | # - "bash <(curl -s https://codecov.io/bash) -r $TRAVIS_REPO_SLUG -t $CODECOV_TOKEN" 57 | 58 | env: 59 | global: 60 | - secure: "H3W2JofszftdPoxll6Y8NFL7d3bblHP9ihiu1N73kvJwgtj/Oyt6Y2F4IBF7jgRFT9/2E8g8X1eOJ8MbZFYvOLyKAIBBQmXcIwE3ScfGPl5LyOwh6NQC1hUCKUZDUiMKmhbFuqazlTgFcva/9mnjpJbKX7VNZSRtnMg/abVEcAg=" 61 | - secure: "lEBD97v+ZHE67fEntCNXyEStuHdyHcHw3rzpZkRLPpBxN8r5MwZY0vMrzEL1CRrgayAKht++vg7l5TbZH/RhiN4Ks649MTd8wihTjZ79Z/9DfygQOtzIusXPncisL7lO51D9ifpnZFzuMwWlHDAMwq9TuTO5lPUQfZgT1OkTJDo=" 62 | -------------------------------------------------------------------------------- /core/src/test/scala/delorean/ConversionSpec.scala: -------------------------------------------------------------------------------- 1 | //: ---------------------------------------------------------------------------- 2 | //: Copyright (C) 2016 Verizon. All Rights Reserved. 3 | //: 4 | //: Licensed under the Apache License, Version 2.0 (the "License"); 5 | //: you may not use this file except in compliance with the License. 6 | //: You may obtain a copy of the License at 7 | //: 8 | //: http://www.apache.org/licenses/LICENSE-2.0 9 | //: 10 | //: Unless required by applicable law or agreed to in writing, software 11 | //: distributed under the License is distributed on an "AS IS" BASIS, 12 | //: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | //: See the License for the specific language governing permissions and 14 | //: limitations under the License. 15 | //: 16 | //: ---------------------------------------------------------------------------- 17 | package delorean 18 | 19 | import scala.concurrent._ 20 | import scala.concurrent.duration._ 21 | 22 | import scalaz.concurrent.Task 23 | 24 | import org.scalatest._ 25 | import org.scalatest.prop._ 26 | import org.scalacheck._ 27 | 28 | import compatibility._ 29 | 30 | class ConversionSpec extends FlatSpec with Matchers with PropertyChecks { 31 | import Arbitrary._ 32 | 33 | implicit val ec = scala.concurrent.ExecutionContext.Implicits.global 34 | 35 | behavior of "task-future conversions" 36 | 37 | it should "convert a future to a task that produces the same value" in { 38 | forAll { str: String => 39 | val f = Future(str) 40 | val t = f.toTask 41 | 42 | t.unsafePerformSync shouldEqual str 43 | } 44 | } 45 | 46 | it should "not eagerly evaluate input futures" in { 47 | var flag = false 48 | def f = Future { flag = true } 49 | val t = f.toTask 50 | 51 | Thread.sleep(250) // ewwwwwwwwwwww 52 | flag shouldEqual false 53 | } 54 | 55 | it should "convert a task to a future that produces the same value" in { 56 | forAll { str: String => 57 | val t = Task now str 58 | val f = t.unsafeToFuture 59 | 60 | Await.result(f, Duration.Inf) shouldEqual str 61 | } 62 | } 63 | 64 | it should "convert a task to a future that produces the same error" in { 65 | case object TestException extends Exception 66 | 67 | val t: Task[String] = Task fail TestException 68 | val f = t.unsafeToFuture 69 | 70 | try { 71 | Await.result(f, Duration.Inf) 72 | 73 | fail() 74 | } catch { 75 | case TestException => true shouldEqual true // I need a pass() function 76 | case _: Throwable => fail() 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Delorean 2 | 3 | ![image](docs/img/logo.png) 4 | 5 | [![Build Status](https://travis-ci.org/Verizon/delorean.svg?branch=master)](https://travis-ci.org/Verizon/delorean) 6 | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.verizon.delorean/core_2.11/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.verizon.delorean/core_2.11) 7 | 8 | Trivial library for correct and stable conversions between `Task` and `Future`. To use: 9 | 10 | For `scalaz-7.1.x`: 11 | ```sbt 12 | libraryDependencies += "io.verizon.delorean" %% "core" % "1.2.40-scalaz-7.1" 13 | ``` 14 | 15 | For `scalaz-7.2.x`: 16 | ```sbt 17 | libraryDependencies += "io.verizon.delorean" %% "core" % "1.2.40-scalaz-7.2" 18 | ``` 19 | 20 | `scalaz-7.0.x` is not [supported](https://github.com/Verizon/delorean/issues/4). 21 | 22 | Cross builds are available for 2.10.x, 2.11.x and for 2.12.x 23 | 24 | ## Usage 25 | 26 | Keep it simple: 27 | 28 | ```scala 29 | import delorean._ // conversions are in the package object 30 | 31 | val f: Future[Foo] = ... 32 | val t: Task[Foo] = f.toTask 33 | val f2: Future[Foo] = t.unsafeToFuture 34 | ``` 35 | 36 | As a general rule of thumb: 37 | 38 | ```scala 39 | def toTask[A](f: Future[A]) = Task { Await.result(f, Duration.Inf) } 40 | def unsafeToFuture[A](t: Task[A]) = Future { t.run } 41 | ``` 42 | 43 | Obviously, the above is misleading since the definitions of these functions are non-blocking, but this should give you an idea of their rough semantics. 44 | 45 | There are a few subtle things that are hidden here by the pretty syntax. 46 | 47 | - `toTask` is lazy in the `Future` parameter, meaning that evaluation of the method receiver will be deferred. This is significant as `Future` is eagerly evaluated and caching. It is ideal to ensure that you do not accidentally eagerly evaluate `Future` values before they are fed into `toTask` (note: we break this rule in the above example, since `f` is a `val`) 48 | - The `Task` resulting from `toTask` will have sane semantics (i.e. it will behave like a normal `Task`) with respect to reevaluation and laziness, provided that you are disciplined and ensure that the `Future` value that is the dispatch receiver is not eagerly evaluated elsewhere (e.g. in a `val`). This means that you can reason about the results of `toTask` in a referentially transparent fashion, as if the constituent `Future` had been constructed as a `Task` all along. 49 | - `toTask` takes an implicit `ExecutionContext` *and* an implicit `Strategy`. You should make sure that the appropriate values of each are in scope. If you are not overriding Scalaz's default implicit `Strategy` for the rest of your `Task` composition, then you can just rely on the default `Strategy`. The point is just to make sure that the `Task` resulting from `toTask` is context-shifted into the same thread pool you're using for "normal" `Task`(s). 50 | - `unsafeToFuture` is exactly as unsafe as it sounds, since the `Future` you get back will be running *eagerly*. Do *not* make use of this function unless you are absolutely sure of what you're doing! It is very dangerous, because it defeats the expected laziness of your `Task` computation. This function is meant primarily for interop with legacy libraries that require values of type `scala.concurrent.Future`. 51 | - `toTask` and `unsafeToFuture` are not strict inverses. They add overhead and defeat fairness algorithms in *both* scala.concurrent and scalaz/scalaz-stream. So… uh… don't repeatedly convert back and forth, k? 52 | 53 | ### Pitfalls 54 | 55 | There are two major pitfalls here. First, the `toTask` conversion can only give you a referentially transparent `Task` if you religiously avoid eagerly caching its dispatch receiver. As a general rule, this isn't a bad idiom: 56 | 57 | ```scala 58 | def f: Future[A] = ??? 59 | 60 | val t: Task[A] = f.toTask 61 | ``` 62 | 63 | In other words, `f` is a `def` and not a `val`. With this sort of machinery, `toTask` will give you a reasonable output. If you eagerly cache its input `Future` though, the results are on your own head. 64 | 65 | Second, `unsafeToFuture` *immediately* runs the input `Task` (as mentioned above). There really isn't anything else that could be done here, since `Future` is eager, but it's worth mentioning. Additionally, `unsafeToFuture` makes no attempt to thread-shift the input `Task`, since in general this is not possible (or necessarily desirable). The resulting `Future` will be on the appropriate thread pool, and it is certainly safe to `flatMap` on said `Future` and treat it normally, but the computation itself will be run on whatever thread scheduler the `Task` was composed against. 66 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner]. 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | 204 | --------------------------------------------------------------------------------